home *** CD-ROM | disk | FTP | other *** search
/ Aminet 1 (Walnut Creek) / Aminet - June 1993 [Walnut Creek].iso / usenet / sources / volume89 / languags / a68k242.3 < prev    next >
Text File  |  1989-03-08  |  65KB  |  2,191 lines

  1. Path: xanth!ukma!tut.cis.ohio-state.edu!mailrus!bbn!ulowell!page
  2. From: page@swan.ulowell.edu (Bob Page)
  3. Newsgroups: comp.sources.amiga
  4. Subject: v89i025:  a68k - 68000 assembler v2.42, Part03/04
  5. Message-ID: <12036@swan.ulowell.edu>
  6. Date: 8 Mar 89 01:49:32 GMT
  7. Organization: University of Lowell, Computer Science Dept.
  8. Lines: 2180
  9. Approved: page@swan.ulowell.edu
  10.  
  11. Submitted-by: jlydiatt@jlami.wimsey.bc.ca (Jeff Lydiatt)
  12. Posting-number: Volume 89, Issue 25
  13. Archive-name: languages/a68k242.3
  14.  
  15. #    This is a shell archive.
  16. #    Remove everything above and including the cut line.
  17. #    Then run the rest of the file through sh.
  18. #----cut here-----cut here-----cut here-----cut here----#
  19. #!/bin/sh
  20. # shar:    Shell Archiver
  21. #    Run the following text with /bin/sh to create:
  22. #    A68kdef.h
  23. #    Adirect.c
  24. #    Codegen.c
  25. #    Opcodes.c
  26. # This archive created: Tue Mar  7 20:42:01 1989
  27. cat << \SHAR_EOF > A68kdef.h
  28. /*------------------------------------------------------------------*/
  29. /*                                    */
  30. /*              MC68000 Cross Assembler                */
  31. /*                                    */
  32. /*           Copyright (c) 1985 by Brian R. Anderson            */
  33. /*                                    */
  34. /*        #define    statements - January 6,    1989            */
  35. /*                                    */
  36. /*   This program may be copied    for personal, non-commercial use    */
  37. /*   only, provided that the above copyright notice is included        */
  38. /*   on    all copies of the source code.    Copying    for any    other use   */
  39. /*   without the consent of the    author is prohibited.            */
  40. /*                                    */
  41. /*------------------------------------------------------------------*/
  42. /*                                    */
  43. /*        Originally published (in Modula-2) in            */
  44. /*        Dr.    Dobb's Journal, April, May, and June 1986.          */
  45. /*                                    */
  46. /*     AmigaDOS conversion copyright 1989 by Charlie Gibbs.        */
  47. /*                                    */
  48. /*------------------------------------------------------------------*/
  49.  
  50. #ifdef AZTEC_C
  51. #include <ctype.h>
  52. #endif
  53. extern char *malloc();
  54. extern int  open(), creat(), read(), write(), close(), unlink();
  55. extern long lseek();
  56.  
  57. #define    TRUE  1
  58. #define    FALSE 0
  59. #define    NODEF 32767    /* High    line number for    undefined symbols */
  60.  
  61. /* Assembler configuration parameters */
  62. #define    MAXLINE      128    /* Longest source line */
  63. #define    MAXFN      41    /* Maximum length of file name */
  64. #define    MAXSREC      16    /* Maximum S-record data length    */
  65. #define    MAXREF      4    /* Number of line numbers in reference entry */
  66. #define    DEFHASH      2047    /* Default number of elements in hash table */
  67. #define    DEFHEAP2  1024    /* Default size    for secondary heap */
  68. #define    INCSKSIZ  2048    /* Size    of INCLUDE skip    table */
  69. #ifdef MSDOS
  70. #define    CHUNKSIZE 2048    /* Memory chunks for Itty Bitty    Memories */
  71. #else
  72. #define    CHUNKSIZE 8192    /* Size    of memory chunks allocated for tables */
  73. #endif
  74. #define    BUFFSIZE  2048    /* File    buffer size */
  75. #define    ObjMAX      32    /* Max.    hex object code    digits in listing */
  76.  
  77. /* Hunk    number definitions */
  78. #define    HunkNone 0    /* Not in a hunk */
  79. #define    HunkUnit 999
  80. #define    HunkName 1000
  81. #define    HunkCode 1001
  82. #define    HunkData 1002
  83. #define    HunkBSS     1003
  84. #define    HunkR32     1004
  85. #define    HunkR16     1005
  86. #define    HunkR8     1006
  87. #define    HunkExt     1007
  88. #define    HunkSym     1008
  89. #define    HunkDbg     1009
  90. #define    HunkEnd     1010
  91.  
  92. #define    MEMF_FAST 0x80000000L    /* Hunk    must load in FAST memory */
  93. #define    MEMF_CHIP 0x40000000L    /* Hunk    must load in CHIP memory */
  94.  
  95. /* Hunk    numbers    denoting special symbol    attributes */
  96. #define    ABSHUNK    32767    /* Absolute */
  97.  
  98. /* Addressing mode flag    values */
  99. #define    DReg   1   /* Data Register */
  100. #define    ARDir  2   /* Address Register Direct */
  101. #define    ARInd  3   /* Address Register Indirect    */
  102. #define    ARPost 4   /* Address Register with Post-Increment */
  103. #define    ARPre  5   /* Address Register with Pre-Decrement */
  104. #define    ARDisp 6   /* Address Register with Displacement */
  105. #define    ARDisX 7   /* Address Register with Disp. & Index */
  106. #define    AbsW   8   /* Absolute Short (16-bit Address) */
  107. #define    AbsL   9   /* Absolute Long (32-bit Address) */
  108. #define    PCDisp 10  /* Program Counter Relative,    with Displacement */
  109. #define    PCDisX 11  /* Program Counter Relative,    with Disp. & Index */
  110. #define    Imm    12  /* Immediate    */
  111. #define    MultiM 13  /* Multiple Register    Move */
  112. #define    SR     14  /* Status Register */
  113. #define    CCR    15  /* Condition    Code Register */
  114. #define    USP    16  /* User's Stack Pointer */
  115. #define    Null   0   /* Error Condition, or Operand missing */
  116.  
  117. #define    X0   0       /* Register types */
  118. #define    Dreg 1
  119. #define    Areg 2
  120.  
  121. #define    S0   0       /* Size types */
  122. #define    Byte 1
  123. #define    Word 2
  124. #define    S3   3
  125. #define    Long 4
  126.  
  127. #define    CMPM  0xB108
  128. #define    JMP   0x4EC0
  129. #define    JSR   0x4E80
  130. #define    LEA   0x41C0
  131. #define    LINK  0x4E50
  132. #define    NOP   0x4E71
  133. #define    PEA   0x4840
  134. #define    STOP  0x4E72
  135. #define    SWAP  0x4840
  136. #define    UNLK  0x4E58
  137.  
  138. #define    None     0    /* Assembler directives    */
  139. #define    Org     1
  140. #define    DC     2
  141. #define    DS     3
  142. #define    Even     4
  143. #define    End     5
  144. #define    Cnop     6
  145. #define    Section     7
  146. #define    CSeg     8
  147. #define    DSeg     9
  148. #define    BSS    10
  149. #define    Idnt    11
  150. #define    DCB    12
  151. #define    Near    13
  152. #define    Far    14
  153. #define    BadMac    15
  154. #define    SkipDir    16    /* Skippable INCLUDE directives    start here */
  155. #define    Equ    16
  156. #define    Public    17
  157. #define    Xdef    18
  158. #define    Xref    19
  159. #define    Page    20
  160. #define    DoList    21
  161. #define    NoList    22
  162. #define    Space    23
  163. #define    Title    24
  164. #define    Include    25
  165. #define    Set    26
  166. #define    Macro    27
  167. #define    IfEQ    28
  168. #define    IfNE    29
  169. #define    IfGT    30
  170. #define    IfGE    31
  171. #define    IfLT    32
  172. #define    IfLE    33
  173. #define    IfC    34
  174. #define    IfNC    35
  175. #define    IfD    36
  176. #define    IfND    37
  177. #define    EndC    38
  178. #define    Equr    39
  179. #define    Reg    40
  180. #define    MacCall    41
  181.  
  182. /* BITSETs of the modes    MISSING    from effective address modes  */
  183. #define     ea 0x0000   /*    Effective addressing - all modes */
  184. #define    dea 0x0002   /*    Data effective addressing     */
  185. #define    mea 0x0003   /*    Memory effective addressing     */
  186. #define    cea 0x081B   /*    Control    effective addressing     */
  187. #define    aea 0x0E00   /*    Alterable effective addressing     */
  188. #define    xxx 0xE000   /*    extra modes: CCR/SR/USP         */
  189.  
  190. #define    IN &        /* Simulated BITSET test */
  191.  
  192. /* AdrModeA bit    definitions */
  193. #define    RegMem3    0x0001    /* 0 = register, 1 = memory */
  194. #define    Ry02    0x0002    /* Register Rx - bits 0-2 */
  195. #define    Rx911    0x0004    /* Register Ry - bits 9-11 */
  196. #define    Data911    0x0008    /* Immediate data - bits 9-11 */
  197. #define    CntR911    0x0010    /* Count register or immediate data */
  198. #define    Brnch    0x0020    /* Relative branch */
  199. #define    DecBr    0x0040    /* Decrement and branch    */
  200. #define    Data03    0x0080    /* TRAP    vector in 0-3 */
  201. #define    Data07    0x0100    /* Data    in 0-7 (MOVEQ) */
  202. #define    OpM68D    0x0200    /* Data    register in 6-8    */
  203. #define    OpM68A    0x0400    /* Address register in 6-8 (ADDA/CMPA/SUBA) */
  204. #define    OpM68C    0x0800    /* CMP (Compare) */
  205. #define    OpM68X    0x1000    /* EOR (Exclusive or) */
  206. #define    OpM68S    0x2000    /* EXT (Sign extension)    */
  207. #define    OpM68R    0x4000    /* MOVEP (Register/memory) */
  208. #define    OpM37    0x8000    /* EXG (Exchange registers) */
  209. #define    TwoOpsA    0xDF4D    /* Two operands    are required */
  210.  
  211. /* AdrModeB bit    definitions */
  212. #define    Bit811    0x0001    /* Bit operations - bits 8-11 as switch    */
  213. #define    Size67    0x0002    /* 00 =    byte, 01 = word, 10 = long */
  214. #define    Size6    0x0004    /* 0 = word, 1 = long */
  215. #define    Sz1213A    0x0008    /* 01 =    byte, 11 = word, 10 = long */
  216. #define    Sz1213    0x0010    /* 11 =    word, 10 = long    */
  217. #define    Exten    0x0020    /* Opcode extension is required    */
  218. #define    EA05a    0x0040    /* Effective address - all */
  219. #define    EA05b    0x0080    /* All except ARDir */
  220. #define    EA05c    0x0100    /* All except ARDIR and    Imm */
  221. #define    EA05d    0x0200    /* All except PCDisp, PCDisx, and Imm */
  222. #define    EA05e    0x0400    /* All except ARDir, PCDisp, PCDisx, and Imm */
  223. #define    EA05f    0x0800    /* All except Dreg, ARDir, ARPost, ARPre, Imm */
  224. #define    EA05x    0x1000    /* Dual    mode - AND/OR */
  225. #define    EA05y    0x2000    /* Dual    mode - ADD/SUB */
  226. #define    EA05z    0x4000    /* Dual    mode - MOVEM */
  227. #define    EA611    0x8000    /* Eff.    Adr. in    6-11 (used only    by MOVE) */
  228. #define    TwoOpsB    0xF3DD    /* Two operands    are required */
  229. #define    ImmMode    0x0422    /* Immediate instructions */
  230. #define    SrcPC    0xF8C0    /* Source operand may be PCDisp    */
  231.  
  232. #define    Dummy     0    /* Error codes */
  233. #define    AlignErr 1
  234. #define    NoCode     2
  235. #define    SymDup     3
  236. #define    Undef     4
  237. #define    ModeErr     5
  238. #define    OperErr     6
  239. #define    BraErr     7
  240. #define    AddrErr     8
  241. #define    SizeErr     9
  242. #define    EndErr     10
  243. #define    AbsReq     11
  244. #define    RelErr     12
  245. #define    NoIncl     13
  246. #define    FwdRef     14
  247. #define    NotSFmt     15
  248. #define    NeedLab     16
  249. #define    Phase     17
  250. #define    NoENDM     18
  251. #define    NoENDC     19
  252. #define    ManyENDC 20
  253. #define    DCOflo     21
  254. #define    ManySect 22
  255. #define    DupMac     23
  256. #define    MultLab     24
  257. #define    NoStrEnd 25
  258. #define    BccSDsp0 26
  259.  
  260. #define    ERRMAX 10    /* Size    of error message table */
  261. SHAR_EOF
  262. cat << \SHAR_EOF > Adirect.c
  263. /*------------------------------------------------------------------*/
  264. /*                                    */
  265. /*              MC68000 Cross Assembler                */
  266. /*                                    */
  267. /*          Copyright    (c) 1985 by Brian R. Anderson            */
  268. /*                                    */
  269. /*      Assembler directive processing - January 6, 1989        */
  270. /*                                    */
  271. /*   This program may be copied    for personal, non-commercial use    */
  272. /*   only, provided that the above copyright notice is included        */
  273. /*   on    all copies of the source code.    Copying    for any    other use   */
  274. /*   without the consent of the    author is prohibited.            */
  275. /*                                    */
  276. /*------------------------------------------------------------------*/
  277. /*                                    */
  278. /*        Originally published (in Modula-2) in            */
  279. /*        Dr.    Dobb's Journal, April, May, and June 1986.          */
  280. /*                                    */
  281. /*     AmigaDOS conversion copyright 1989 by Charlie Gibbs.        */
  282. /*                                    */
  283. /*------------------------------------------------------------------*/
  284.  
  285. #include <stdio.h>
  286. #include "a68kdef.h"
  287. #include "a68kglb.h"
  288.  
  289. /* Functions */
  290. extern int  LineParts(), Instructions();
  291. extern int  GetInstModeSize(), GetMultReg(), CountNest();
  292. extern int  ReadSymTab(), GetArgs(), GetAReg(),    OpenIncl();
  293. extern long AddrBndW(),    AddrBndL(), GetValue(),    CalcValue();
  294. extern char *AddName(),    *GetField();
  295. extern struct SymTab *NextSym();
  296. extern struct SymTab **HashIt();
  297.  
  298.  
  299.  
  300. int ObjDir (dummy) int dummy;
  301. /* Generates Object Code for Assembler Directives */
  302. {
  303.     register char *s, *t;
  304.     register int i, j;
  305.     int     oploc;
  306.     long templong;
  307.     char tempop[MAXLINE], delim;
  308.     struct SetFixup *sf;
  309.  
  310.     switch (Dir) {
  311.  
  312.     case Org:                        /* ORG */
  313.     PrntAddr = MakeHunk = TRUE;
  314.     templong = GetValue (SrcOp, SrcLoc);
  315.     if (DefLine2 >=    LineCount) {
  316.         Error (SrcLoc, FwdRef);    /* Illegal forward reference */
  317.         break;
  318.     }
  319.     if (OpCode[0] == 'R') {                         /* RORG */
  320.         if (Hunk2 != ABSHUNK) {
  321.         Error (SrcLoc, RelErr);    /* RORG    needs absolute value */
  322.         break;
  323.         }
  324.     } else if (Hunk2 != CurrHunk) {
  325.         Error (SrcLoc, RelErr);    /* Can't ORG out of hunk */
  326.         break;
  327.     }
  328.  
  329.     if ((!Pass2 || (HunkType == HunkBSS))
  330.     && (templong < AddrCnt)    /* If we're ORGing to a lower address  */
  331.     && (AddrCnt > OrgHigh))    /*  and    this is    the highest we've been */
  332.         OrgHigh = AddrCnt;    /*  remember how far we    got.           */
  333.  
  334.     AddrCnt    = templong;    /* Update the location counter */
  335.     OrgFlag    = TRUE;        /* Indicate object fixups are needed */
  336.     break;
  337.  
  338.     case Equ:                        /* EQU */
  339.     if (Label[0] ==    '\0')
  340.         Error (0, NeedLab);        /* Need    a label    */
  341.     ObjSrc = GetValue (SrcOp, SrcLoc);
  342.     if (DefLine2 >=    LineCount)
  343.         Error (SrcLoc, FwdRef);    /* Illegal forward reference */
  344.     Src.Hunk = Hunk2;
  345.     PrntAddr = MakeHunk = TRUE;
  346.     break;
  347.  
  348.     case DC:                        /* DC */
  349.     if ((Size == Word) || (Size == Long))
  350.         AddrCnt = AddrBndW (AddrCnt);
  351.     s = Line + SrcLoc;
  352.     while (!isspace(*s) && (*s != '\0') && (*s != ';')) {
  353.         oploc = s -    Line;
  354.         if (((*s ==    '\'') || (*s == '"'))   /* String */
  355.         && (Size ==    Byte)) {
  356.         delim =    *s++;            /* Get the delimiter */
  357.         while (1) {
  358.             if (*s == '\0') {           /* No closing delimiter */
  359.             Error (s-Line, NoStrEnd);
  360.             break;
  361.             }
  362.             if (*s == delim) {        /* End of string? */
  363.             if (*(++s) != delim)    /* Check next character    */
  364.                 break;        /* End of string */
  365.             }    /* Otherwise it's an apostrophe in the string */
  366.             Src.Hunk = ABSHUNK;        /* Absolute value */
  367.             ObjString[nX++] = *s++;    /* Current character */
  368.         }
  369.         } else {            /* Not a string    constant */
  370.         s = GetField (s, SrcOp);
  371.         ObjSrc = GetValue (SrcOp, oploc);    /* Value */
  372.         if ((Src.Hunk =    Hunk2) != ABSHUNK) {    /* Hunk    no. */
  373.             templong = AddrCnt + nX;        /* Relocatable */
  374.             PutRel (templong, Hunk2, Size);
  375.         }
  376.         if (Size == 4) {
  377.             ObjString[nX++] = (ObjSrc >> 24) & 0x00FF;
  378.             ObjString[nX++] = (ObjSrc >> 16) & 0x00FF;
  379.         }
  380.         if (Size >= 2)
  381.             ObjString[nX++] = (ObjSrc >> 8) & 0x00FF;
  382.         ObjString[nX++]    = ObjSrc & 0x00FF;
  383.         if (Size == 2)
  384.             templong = 0xFFFF0000L;
  385.         else if    (Size == 1)
  386.             templong = 0xFFFFFF00L;
  387.         if (Size < 4)
  388.             if (((ObjSrc & templong) !=    0)
  389.             && ((ObjSrc    & templong) != templong))
  390.             Error (s-Line, SizeErr);
  391.         }
  392.         if (*s == ',')
  393.         s++;            /* Skip    over separator */
  394.     }
  395.     if (!isspace(*s) && (*s    != '\0') && (*s != ';'))
  396.         Error (s-Line, OperErr);    /* Didn't end properly */
  397.     AddrAdv    = InstSize = nX;
  398.     PrntAddr = MakeHunk = TRUE;
  399.     break;
  400.  
  401.     case DS:                        /* DS */
  402.     if (DestLoc != 0) {
  403.         Error (DestLoc, OperErr);    /* Only    one operand is allowed */
  404.         PrntAddr = MakeHunk    = TRUE;
  405.         break;
  406.     }
  407.     AddrAdv    = GetValue (SrcOp, SrcLoc);
  408.     if (DefLine2 >=    LineCount) {
  409.         Error (SrcLoc, FwdRef);    /* Illegal forward reference */
  410.         AddrAdv = 0;
  411.     }
  412.     if (Hunk2 != ABSHUNK)
  413.         Error (SrcLoc, AbsReq);    /* Count must be absolute */
  414.  
  415.     if (Size == Word) {        /* Words */
  416.         AddrCnt = AddrBndW (AddrCnt);
  417.         AddrAdv <<=    1;
  418.     }
  419.     if (Size == Long) {        /* Long    words */
  420.         AddrCnt = AddrBndW (AddrCnt);
  421.         AddrAdv <<=    2;
  422.     }
  423.     if (Pass2 && (HunkType != HunkBSS)) {    /* If this isn't     */
  424.         templong = AddrAdv;            /*  a BSS hunk,         */
  425.         while (templong >= 4) {        /*  generate zeros   */
  426.         AppendSdata (0L, 4);        /*  to fill the    area */
  427.         templong -= 4;
  428.         }
  429.         if (templong > 0) {
  430.         i = templong;
  431.         AppendSdata (0L, i);
  432.         }
  433.     }
  434.     PrntAddr = MakeHunk = TRUE;
  435.     break;
  436.  
  437.     case Even:                        /* EVEN    */
  438.     AddrCnt    = AddrBndW (AddrCnt);
  439.     PrntAddr = MakeHunk = TRUE;
  440.     break;
  441.  
  442.     case End:                        /* END */
  443.     if (Pass2)
  444.         if (SrcOp[0] != '\0')
  445.         EndAddr    = GetValue (SrcOp, SrcLoc);
  446.         else
  447.         EndAddr    = 0;
  448.     PrntAddr = MakeHunk = TRUE;
  449.     break;
  450.  
  451.     case Xdef:                        /* XDEF    */
  452.     case Public:                    /* PUBLIC */
  453.     if (SFormat)
  454.         Error (OpLoc, NotSFmt);        /* Not in S-format */
  455.     s = Line + SrcLoc;
  456.     while (!isspace(*s) && (*s != '\0')) {
  457.         oploc = s -    Line;
  458.         s =    GetField (s, SrcOp);        /* Get a symbol    */
  459.         if (ReadSymTab (SrcOp)) {
  460.         if (!Pass2) {
  461.             if ((Sym->Flags & 0x61) == 0) {
  462.             Sym->Flags |= 2;    /* Set XDEF flag */
  463.             if (OpCode[0] == 'P') {
  464.                 Sym->Flags |= 0x80;    /* Defined as PUBLIC */
  465.             }
  466.             }
  467.         } else {
  468.             if (Sym->Defn != LineCount)    /* If not PUBLIC->XREF */
  469.             AddRef (LineCount);    /*  it's a reference  */
  470.             if (Sym->Defn == NODEF)
  471.             Error (oploc, Undef);    /* Never got defined */
  472.             else if (Sym->Flags    & 0x60)
  473.             Error (oploc, AddrErr);    /* Can't XDEF a register */
  474.         }
  475.         } else if (!Pass2) {        /* Not yet defined */
  476.         if (OpCode[0] == 'P') {         /* Treat PUBLIC as XREF */
  477.             AddSymTab (SrcOp, 0L, 0L ,LineCount, 0x81);
  478.             Sym->Hunk =    ~((long) Sym->Nam);
  479.         } else {
  480.             AddSymTab (SrcOp, 0L, CurrHunk, NODEF, 2);    /* XDEF    */
  481.         }
  482.         }
  483.         if (*s == ',')
  484.         s++;                /* Skip    over separator */
  485.     }
  486.     break;
  487.  
  488.     case Xref:                        /* XREF    */
  489.     if (SFormat)
  490.         Error (OpLoc, NotSFmt);        /* Not in S-format */
  491.     s = Line + SrcLoc;
  492.     while (!isspace(*s) && (*s != '\0')) {
  493.         oploc = s -    Line;
  494.         s =    GetField (s, SrcOp);
  495.         if (Pass2) {
  496.         if (ReadSymTab (SrcOp))    {
  497.             if (Sym->Defn != LineCount)    {
  498.             AddRef (LineCount); /* Ignore extraneous XREF */
  499.             }
  500.         }
  501.         } else {
  502.         if (!ReadSymTab    (SrcOp)) {    /* Only    if not defined */
  503.             AddSymTab (SrcOp, 0L, 0L, LineCount, 1);
  504.             Sym->Hunk =    ~((long) Sym->Nam);
  505.         }
  506.         }
  507.         if (*s == ',')
  508.         s++;            /* Skip    over separator */
  509.     }
  510.     break;
  511.  
  512.     case Page:                        /* PAGE    */
  513.     if (Pass2 && (LineCount    > 1))    /* Ignore PAGE at start    of file    */
  514.         LnCnt = LnMax;        /* Resume on a new page    */
  515.     break;
  516.  
  517.     case DoList:                    /* LIST    */
  518.     ListOff    = FALSE;
  519.     if (!Pass2 && !SuppList    && (IncStart !=    0)) {
  520.         IncStart = 0;            /* We can't      */
  521.         if (SkipLim->Set1 != NULL) {    /*  skip this     */
  522.         SetFixLim = SkipLim->Set1;    /*  INCLUDE file */
  523.         SetFixLim++;            /*  in pass 2     */
  524.         }                    /*  (we    must     */
  525.     }                    /*  list it).     */
  526.     break;
  527.  
  528.     case NoList:                    /* NOLIST */
  529.     ListOff    = TRUE;
  530.     break;
  531.  
  532.     case Space:                        /* SPC */
  533.     if (Pass2 && !ListOff && !SuppList) {
  534.         if (SrcOp[0] != '\0')
  535.         j = GetValue (SrcOp, SrcLoc);    /* Amount to space */
  536.         else
  537.         j = 1;                /* Default to one line */
  538.         for    (i = 0;    i < j; i++) {
  539.         if (LnCnt >= LnMax)
  540.             break;            /* Page    overflow */
  541.         xputs (&List, "\n");            /* Space one line */
  542.         }
  543.     }
  544.     break;
  545.  
  546.     case Title:                        /* TTL */
  547.     s = Line + SrcLoc;
  548.     t = TTLstring;
  549.     while (*s && (s    < (TTLstring+MAXLINE)))
  550.         *t++ = *s++;        /* Get title string */
  551.     *t = '\0';
  552.     if (LineCount >    1) {
  553.         LnCnt = LnMax;        /* Skip    to a new page */
  554.     } else {
  555.         if (Pass2) {
  556.         xputs (&List, TTLstring);
  557.         xputs (&List, "\n\n");
  558.         }
  559.         LnCnt += 2;            /* Don't skip at start of file */
  560.     }
  561.     break;
  562.  
  563.     case Cnop:                        /* CNOP    */
  564.     i = TRUE;            /* "Error-free" flag */
  565.  
  566.     ObjSrc = GetValue (SrcOp, SrcLoc);
  567.     if (DefLine2 >=    LineCount) {
  568.         Error (SrcLoc, FwdRef);    /* Illegal forward reference */
  569.         i =    FALSE;
  570.     }
  571.     if (Hunk2 != ABSHUNK) {
  572.         Error (SrcLoc, AbsReq);    /* Must    be absolute! */
  573.         i =    FALSE;
  574.     }
  575.  
  576.     ObjDest    = GetValue (DestOp, DestLoc);
  577.     if (DefLine2 >=    LineCount) {
  578.         Error (DestLoc, FwdRef);    /* Illegal forward reference */
  579.         i =    FALSE;
  580.     }
  581.     if (Hunk2 != ABSHUNK) {
  582.         Error (DestLoc, AbsReq);    /* Must    be absolute! */
  583.         i =    FALSE;
  584.     }
  585.  
  586.     templong = ObjDest;
  587.     while ((templong > 0) && ((templong & 1) == 0))
  588.         templong >>= 1;        /* Shift out low-order zeros */
  589.     if ((templong != 1) || (ObjDest    == 1)) {
  590.         Error (DestLoc, OperErr);    /* DestOp must be a power of 2 */
  591.         i =    FALSE;
  592.     }
  593.     if ((ObjSrc & 1) || (ObjSrc >= ObjDest)) {
  594.         Error (SrcLoc, OperErr);    /* SrcOp is odd    or out of range    */
  595.         i =    FALSE;
  596.     }
  597.  
  598.     if (i) {            /* If no errors    so far */
  599.         AddrCnt = AddrBndW (AddrCnt);
  600.         templong = (AddrCnt    & ~(ObjDest-1))    + ObjSrc;
  601.         if (templong < AddrCnt)
  602.         templong += ObjDest;    /* We must advance to here */
  603.         if ((templong - AddrCnt) < MAXLINE)    {
  604.         nX = templong -    AddrCnt;
  605.         for (j = 0; j <    nX; ) {
  606.             ObjString[j++] = NOP / 256;
  607.             ObjString[j++] = NOP & 255;
  608.         }
  609.         AddrAdv    = InstSize = nX;    /* generate NOPs */
  610.         PrntAddr = MakeHunk = TRUE;
  611.         } else {
  612.         Error (DestLoc,    OperErr);    /* Too many NOPs */
  613.         }
  614.     }
  615.     break;
  616.  
  617.     case Include:                    /* INCLUDE */
  618.     if (Pass2                /* If we can skip */
  619.     && (SkipIdx < SkipLim)            /*  this INCLUDE  */
  620.     && (LineCount == SkipIdx->Start)) {    /*  file in pass  */
  621.         LineCount =    SkipIdx->Finish;    /*  2, do so.      */
  622.         MacCount = SkipIdx->MCount;
  623.         if ((sf = SkipIdx->Set1) !=    NULL) {
  624.         while ((sf >= SetFixLim) && (sf->Sym !=    NULL)) {
  625.             (sf->Sym)->Val  = sf->Val;    /* Fix up SET symbols */
  626.             (sf->Sym)->Hunk = sf->Hunk;
  627.             sf--;
  628.         }
  629.         }
  630.         SkipIdx++;
  631.         break;
  632.     }
  633.     if ((Quiet < 0)    && (InF->UPtr == 0))
  634.         ShowLine (InF->Line);    /* Show    where we are */
  635.     s = Line + SrcLoc;
  636.     if ((*s    == '"') || (*s == '\''))
  637.         s++;            /* Ignore quotes */
  638.     t = tempop;
  639.     while (!isspace(*s)
  640.     && (*s != '"')
  641.     && (*s != '\'')
  642.     && (*s != '\0'))
  643.         *t++ = *s++;
  644.     *t = '\0';
  645.     if (InF->UPtr == 0) {
  646.         InF->Pos = lseek (In.fd, 0L, 1);
  647.         InF->Pos -=    In.Lim-In.Ptr;    /* Position in outer file */
  648.     }
  649.     if (!OpenIncl (tempop, InclList)) {
  650.         Error (SrcLoc, NoIncl);    /* Couldn't open file */
  651.         InclErrs = TRUE;
  652.         if (InF->UPtr == 0)    {
  653.         In.fd =    open (InF->NPtr, 0);
  654.         lseek (In.fd, InF->Pos,    0);
  655.         In.Ptr = In.Lim    = In.Buf;
  656.         }
  657.         break;            /* Return to outer file    */
  658.     }
  659.     InFNum++;            /* Bump    nesting    level */
  660.     if (--InF < LowInF)
  661.         LowInF = InF;
  662.     Heap2Space (strlen(tempop)+1);    /* Check for space */
  663.     InF->UPtr = 0;            /* Not a user macro */
  664.     InF->NPtr = NextFNS;        /* New stack pointer */
  665.     strcpy (NextFNS, tempop);    /* File    name */
  666.     NextFNS    += strlen (tempop) + 1;    /* Next    available space    */
  667.     if (NextFNS > High2)
  668.         High2 = NextFNS;        /* Set high-water mark */
  669.     InF->NArg = -1;            /* Indicate it's not a macro */
  670.     InF->Line = 0;            /* Clear line counter */
  671.     InF->MCnt = MacCount;
  672.  
  673.     if (!Pass2 && (SuppList    || ListOff) && (IncStart == 0))    {
  674.         s =    (char *) SkipLim + sizeof (struct SkipEnt);
  675.         if (s <= (char *) SetFixLim) {
  676.         SkipLim->Set1 =    NULL;    /* Save    starting position */
  677.         IncStart = LineCount;    /*  in case we can skip      */
  678.         IncPtr = InF;        /*  this file in pass 2.  */
  679.         }
  680.     }
  681.     break;
  682.  
  683.     case Set:                        /* SET */
  684.     if (Label[0] ==    '\0')
  685.         Error (0, NeedLab);        /* Need    a label    */
  686.     ObjSrc = GetValue (SrcOp, SrcLoc);
  687.     if (DefLine2 >=    LineCount)
  688.         Error (SrcLoc, FwdRef);    /* Illegal forward reference */
  689.     Src.Hunk = Hunk2;
  690.     if (!ReadSymTab    (Label))        /* Make    a new entry */
  691.         AddSymTab (Label, ObjSrc, Src.Hunk,    LineCount, 4);
  692.     else if    (Sym->Flags & 4) {        /* Re-SET the symbol */
  693.         Sym->Val = ObjSrc;            /* SET value */
  694.         Sym->Hunk =    Src.Hunk;        /* Hunk    number */
  695.         Sym->Defn =    LineCount;        /* Statement number */
  696.     }
  697.     PrntAddr = MakeHunk = TRUE;
  698.  
  699.     if (!Pass2 && (IncStart    != 0)) {
  700.         if ((sf = SkipLim->Set1) !=    NULL) {
  701.         while (sf >= SetFixLim)    {
  702.             if (sf->Sym    != Sym)    {
  703.             sf--;
  704.             } else {
  705.             sf->Val     = Sym->Val;    /* Update an        */
  706.             sf->Hunk = Sym->Hunk;    /*  existing entry. */
  707.             return (Set);
  708.             }
  709.         }
  710.         }
  711.         sf = SetFixLim;
  712.         sf--;
  713.         s =    (char *) SkipLim + sizeof (struct SkipEnt);
  714.         if (s > (char *) sf) {
  715.         IncStart = 0;        /* No room for set symbol */
  716.         if (SkipLim->Set1 != NULL) {
  717.             SetFixLim =    SkipLim->Set1;
  718.             SetFixLim++;
  719.         }
  720.         } else {
  721.         if (SkipLim->Set1 == NULL)
  722.             SkipLim->Set1 = sf;    /* First SET symbol in INCLUDE */
  723.         sf->Sym     = Sym;
  724.         sf->Val     = Sym->Val;    /* Save    SET symbol value */
  725.         sf->Hunk = Sym->Hunk;    /*  and    hunk.         */
  726.         SetFixLim = sf;
  727.         }
  728.     }
  729.     break;
  730.  
  731.     case Macro:                        /* MACRO */
  732.     if (Label[0] ==    '\0')
  733.         Error (0, NeedLab);        /* Need    a label    */
  734.  
  735.     s = Label;
  736.     t = tempop;
  737.     *t++ = ' ';                     /* Prepend name with a */
  738.     while (*s)            /*  blank and convert  */
  739.         *t++ = toupper (*s++);    /*  it to upper    case.  */
  740.     *t = '\0';
  741.  
  742.     if (!Pass2) {            /* Pass    1 */
  743.         if (!ReadSymTab (tempop))        /* Save    MACRO name */
  744.         AddSymTab (tempop, 0L, 0L, LineCount, 8);
  745.         Sym->Hunk =    (long) AddName(Line,1);    /* Save    MACRO stmt. */
  746.     } else {            /* Pass    2 */
  747.         ReadSymTab (tempop);
  748.         if (Sym->Defn != LineCount)    {
  749.         Error (LabLoc, DupMac);        /* Duplicate MACRO */
  750.         AddRef (LineCount);
  751.         }
  752.         WriteListLine (&List);        /* Echo    MACRO */
  753.     }
  754.  
  755.     i = 0;                /* IF nest counter */
  756.     while (1) {            /* Process macro body */
  757.         if (LineParts (dummy)) {
  758.         Error (OpLoc, NoENDM);    /* Premature EOF */
  759.         i = 0;
  760.         break;
  761.         }
  762.         if ((i += CountNest    (OpCode)) < 0) {
  763.         Error (OpLoc,ManyENDC);    /* Unmatched ENDC */
  764.         i = 0;
  765.         }
  766.         if (!Pass2)
  767.         AddName    (Line, 2);    /* Store a line    */
  768.         if (strcmp (OpCode,    "ENDM") == 0)
  769.         break;            /* Main    program    echoes ENDM */
  770.         if (Pass2)
  771.         WriteListLine (&List);    /* Echo    a line */
  772.     }
  773.     if (i >    0)
  774.         Error (OpLoc, NoENDC);    /* ENDC    is missing */
  775.  
  776.     break;
  777.  
  778.     case IfEQ:                        /* IFEQ    */
  779.     ObjSrc = GetValue (SrcOp, SrcLoc);
  780.     if (ObjSrc != 0)
  781.         SkipNest++;            /* Skip    to the next ENDC */
  782.     break;
  783.  
  784.     case IfNE:                        /* IFNE    */
  785.     ObjSrc = GetValue (SrcOp, SrcLoc);
  786.     if (ObjSrc == 0)
  787.         SkipNest++;
  788.     break;
  789.  
  790.     case IfGT:                        /* IFGT    */
  791.     ObjSrc = GetValue (SrcOp, SrcLoc);
  792.     if (ObjSrc <= 0)
  793.         SkipNest++;
  794.     break;
  795.  
  796.     case IfGE:                        /* IFGE    */
  797.     ObjSrc = GetValue (SrcOp, SrcLoc);
  798.     if (ObjSrc < 0)
  799.         SkipNest++;
  800.     break;
  801.  
  802.     case IfLT:                        /* IFLT    */
  803.     ObjSrc = GetValue (SrcOp, SrcLoc);
  804.     if (ObjSrc >= 0)
  805.         SkipNest++;
  806.     break;
  807.  
  808.     case IfLE:                        /* IFLE    */
  809.     ObjSrc = GetValue (SrcOp, SrcLoc);
  810.     if (ObjSrc > 0)
  811.         SkipNest++;
  812.     break;
  813.  
  814.     case IfC:                        /* IFC */
  815.     if (strcmp (SrcOp, DestOp) != 0)
  816.         SkipNest++;
  817.     break;
  818.  
  819.     case IfNC:                        /* IFNC    */
  820.     if (strcmp (SrcOp, DestOp) == 0)
  821.         SkipNest++;
  822.     break;
  823.  
  824.     case IfD:                        /* IFD */
  825.     if (ReadSymTab (SrcOp))
  826.         AddRef (LineCount);
  827.     if (DefLine2 > LineCount)
  828.         SkipNest++;
  829.     break;
  830.  
  831.     case IfND:                        /* IFND    */
  832.     if (ReadSymTab (SrcOp))
  833.         AddRef (LineCount);
  834.     if (DefLine2 <=    LineCount)
  835.         SkipNest++;
  836.     break;
  837.  
  838.     case EndC:                        /* ENDC    */
  839.     break;                /* LineParts will take care of it */
  840.  
  841.     case Section:                    /* SECTION */
  842.     if (SFormat)
  843.         Error (OpLoc, NotSFmt);    /* Not in S-format */
  844.     tempop[0] = '\0';
  845.     s = Line + DestLoc + strlen (DestOp);    /* Check for flags */
  846.     if (*s == ',') {
  847.         s++;
  848.         GetField (s, tempop);    /* Get specification */
  849.     }
  850.     DoSection (SrcOp, SrcLoc, DestOp, DestLoc, tempop, j);
  851.     break;
  852.  
  853.     case CSeg:                        /* CODE    */
  854.     if (SFormat)
  855.         Error (OpLoc, NotSFmt);    /* Not in S-format */
  856.     DoSection (SrcOp, SrcLoc, "CODE", OpLoc, DestOp, DestLoc);
  857.     break;                /* Treat as SECTION */
  858.  
  859.     case DSeg:                        /* DATA    */
  860.     if (SFormat)
  861.         Error (OpLoc, NotSFmt);    /* Not in S-format */
  862.     DoSection (SrcOp, SrcLoc, "DATA", OpLoc, DestOp, DestLoc);
  863.     break;                /* Treat as SECTION */
  864.  
  865.     case BSS:                        /* BSS */
  866.     if (SFormat)
  867.         Error (OpLoc, NotSFmt);    /* Not in S-format */
  868.     DoSection (SrcOp, SrcLoc, "BSS", OpLoc, DestOp, DestLoc);
  869.     break;                /* Treat as SECTION */
  870.  
  871.     case Idnt:                        /* IDNT    */
  872.     s = Line + SrcLoc;
  873.     if ((*s    == '"') || (*s == '\''))
  874.         s++;            /* Ignore quotes */
  875.     t = IdntName;
  876.     while (!isspace(*s)
  877.     && (*s != '"')
  878.     && (*s != '\'')
  879.     && (*s != '\0'))
  880.         *t++ = *s++;
  881.     *t = '\0';
  882.     break;
  883.  
  884.     case DCB:                        /* DCB */
  885.     if ((Size == Word) || (Size == Long))
  886.         AddrCnt = AddrBndW (AddrCnt);
  887.     ObjSrc = GetValue (SrcOp, SrcLoc);    /* Replication factor */
  888.     if (DefLine2 >=    LineCount) {
  889.         Error (SrcLoc, FwdRef);    /* Illegal forward reference */
  890.         ObjSrc = 0;
  891.     }
  892.     if (Hunk2 != ABSHUNK) {
  893.         Error (SrcLoc, AbsReq);    /* Must    be absolute! */
  894.         ObjSrc = 0;
  895.     }
  896.     ObjDest    = GetValue (DestOp, DestLoc);    /* Value to replicate */
  897.     Dest.Hunk = Hunk2;
  898.     for (i = 0; i <    ObjSrc;    i++) {
  899.         if (nX >= MAXLINE) {
  900.         Error (SrcLoc, DCOflo);        /* ObjString overflowed    */
  901.         break;
  902.         }
  903.         if (Dest.Hunk != ABSHUNK) {
  904.         templong = AddrCnt + nX;    /* Relocatable */
  905.         PutRel (templong, Hunk2, Size);
  906.         }
  907.         if (Size ==    4) {
  908.         ObjString[nX++]    = (ObjDest >> 24) & 0x00FF;
  909.         ObjString[nX++]    = (ObjDest >> 16) & 0x00FF;
  910.         }
  911.         if (Size >=    2)
  912.         ObjString[nX++]    = (ObjDest >> 8) & 0x00FF;
  913.         ObjString[nX++] = ObjDest &    0x00FF;
  914.     }
  915.     AddrAdv    = InstSize = nX;
  916.     PrntAddr = MakeHunk = TRUE;
  917.     break;
  918.  
  919.     case Equr:                        /* EQUR    */
  920.     if ((i = IsRegister (SrcOp, strlen (SrcOp))) < 0)
  921.         Error (SrcLoc, AddrErr);    /* Not a valid register    */
  922.     if (Label[0] ==    '\0')
  923.         Error (0, NeedLab);        /* Need    a label    */
  924.     else {
  925.         if (!ReadSymTab (Label))    /* Make    a new entry */
  926.         AddSymTab (Label, (long) i, 0L,    LineCount, 0x20);
  927.         GotEqur = TRUE;        /* We have at least one    EQUR */
  928.     }
  929.     break;
  930.  
  931.     case Reg:                        /* REG */
  932.     if (Label[0] ==    '\0')
  933.         Error (0, NeedLab);        /* Need    a label    */
  934.     else {
  935.         if ((i = GetMultReg    (SrcOp,    SrcLoc)) == 0) {
  936.         Error (SrcLoc, OperErr);
  937.         } else {
  938.         if (!ReadSymTab    (Label)) {  /* Make a new entry    */
  939.             AddSymTab (Label, (long) i,    0L, LineCount, 0x40);
  940.             GotEqur = TRUE;        /* We have at least    one EQUR */
  941.         }
  942.         }
  943.     }
  944.     break;
  945.  
  946.     case Near:                        /* NEAR    */
  947.     SmallData = TRUE;    /* Set small-data model    flag */
  948.     AnyNear    = TRUE;        /* Remember that we use    it somewhere */
  949.     break;
  950.  
  951.     case Far:                        /* FAR */
  952.     SmallData = FALSE;    /* Reset small-data model flag */
  953.     break;
  954.  
  955.     default:
  956.     break;
  957.     }
  958.  
  959.     return (Dir);
  960. }
  961.  
  962.  
  963.  
  964. DoSection (name, nameloc, type,    typeloc, flags,    flagloc)
  965. char *name, *type, *flags;
  966. int nameloc, typeloc, flagloc;
  967. /* Processes SECTION directive or equivalent */
  968. {
  969.     static long    HunkPos;    /* Seek    address    of start of section */
  970.     register char *s, *t;
  971.     long newflags, templong;
  972.     char tempop[MAXLINE];
  973.  
  974.     PrntAddr = TRUE;
  975.  
  976.     for    (s = type; *s; s++)        /* Convert section type    */
  977.     *s = toupper (*s);        /*  to upper case */
  978.     if ((type[0] == '\0') || (strcmp (type, "CODE") == 0))
  979.     newflags = HunkCode;        /* Code    section    */
  980.     else if (strcmp (type, "DATA") == 0)
  981.     newflags = HunkData;        /* Data    section    */
  982.     else if (strcmp (type, "BSS") == 0)
  983.     newflags = HunkBSS;        /* BSS section */
  984.     else {
  985.     Error (typeloc,    OperErr);    /* Invalid type    */
  986.     strcpy (type, "CODE");
  987.     newflags = HunkCode;        /* Make    it CODE    */
  988.     }
  989.     newflags <<= 16;    /* Shift to high-order 16 bits */
  990.  
  991.     if (flags[0]) {
  992.     for (s = flags;    *s; s++)        /* Convert flags */
  993.         *s = toupper (*s);            /*  to upper case */
  994.     if (strcmp (flags, "CHIP") == 0)
  995.         newflags |=    MEMF_CHIP;        /* CHIP    memory */
  996.     else if    (strcmp    (flags,    "FAST") == 0)
  997.         newflags |=    MEMF_FAST;        /* FAST    memory */
  998.     else
  999.         Error (flagloc, OperErr);        /* Invalid - ignore */
  1000.     }
  1001.  
  1002.     templong = (newflags & 0xFFFF0000) >> 16;
  1003.     sprintf (tempop,"  %4x",HunkSeq++); /* Make section name unique */
  1004.     s =    name;
  1005.     if ((*s == '"') || (*s == '\''))
  1006.     s++;                /* Ignore quotes */
  1007.     t =    tempop + 6;
  1008.     while (!isspace(*s)
  1009.     && (*s != '"')
  1010.     && (*s != '\'')
  1011.     && (*s != '\0'))
  1012.     *t++ = *s++;            /* Concatenate section name */
  1013.     *t = '\0';
  1014.  
  1015.     if (ReadSymTab (tempop)) {        /* Scan    for section name */
  1016.     if (HunkType ==    HunkNone) {
  1017.         SectLine = 1;        /* Start of first section */
  1018.     } else {
  1019.         if (Pass2) {
  1020.         AddRef (LineCount);
  1021.         DumpSdata (&Srec);    /* Finish the previous hunk */
  1022.         if (!MakeHunk) {    /* If it was a null hunk,   */
  1023.             if (Srec.Ptr > Srec.Buf)    /* overwrite it.    */
  1024.             write (Srec.fd,    Srec.Buf, Srec.Ptr - Srec.Buf);
  1025.             lseek (Srec.fd, HunkPos, 0);
  1026.             Srec.Ptr = Srec.Buf;
  1027.         }
  1028.         } else {
  1029.         AddrCnt    = AddrBndL (AddrCnt);    /* Finish on long word */
  1030.         }
  1031.         if (AddrCnt    > OrgHigh)
  1032.         Sect->Val = AddrCnt;    /* End of old section */
  1033.         else
  1034.         Sect->Val = OrgHigh;    /* We've ORGed higher */
  1035.         SectLine = LineCount;    /* Start of new    section    */
  1036.     }
  1037.     Sect = Sym;            /* Point to new    section    */
  1038.     AddrCnt    = SectStart = Sym->Val;    /* Continuation    */
  1039.     OrgHigh    = 0L;
  1040.     OrgFlag    = FALSE;
  1041.     TempAddr = StartAddr = AddrCnt;
  1042.     CurrHunk = Sym->Hunk & 0x0000FFFFL;        /* Hunk no.    */
  1043.     HunkType = (Sym->Hunk &    0x3FFF0000L) >>    16; /* Type */
  1044.     HunkFlags = Sym->Hunk &    0xC0000000L;        /* Flags */
  1045.     if (Pass2 && !SFormat) {        /* Start a new hunk */
  1046.         HunkPos = lseek (Srec.fd, 0L, 1);
  1047.         HunkPos += Srec.Ptr    - Srec.Buf;    /* It starts here */
  1048.         templong = HunkName;
  1049.         xputl (&Srec, templong);
  1050.         if (tempop[6])
  1051.         DumpName (&Srec, &tempop[6], 0L);   /* Hunk name */
  1052.         else
  1053.         DumpName (&Srec, " ", 0L);
  1054.         xputl (&Srec, HunkType);    /* Hunk    type */
  1055.         LenPtr = Srec.Ptr;        /* Pointer to hunk length */
  1056.         LenPos = lseek (Srec.fd, 0L, 1);
  1057.         LenPos += LenPtr-Srec.Buf;    /* Hunk    length goes here */
  1058.         xputl (&Srec, 0L);        /* For now, set    it to zero */
  1059.     }
  1060.     MakeHunk = FALSE;        /* We don't have anything yet */
  1061.     if (AnyNear && (CurrHunk > 1))
  1062.         Error (OpLoc, ManySect);    /* Too many hunks for small data */
  1063.     return;
  1064.     }
  1065.  
  1066.     AddrCnt = AddrBndL (AddrCnt);    /* Finish on long word bounary */
  1067.  
  1068.     if (Pass2) {
  1069.     Error (OpLoc, ManySect);    /* Table overflowed in pass 1 */
  1070.     return;
  1071.     }
  1072.     if (NextHunk >= ABSHUNK)        /* Set up a new    table entry */
  1073.     return;                /* Section table overflow */
  1074.  
  1075.     if (HunkType != HunkNone) {
  1076.     if (AddrCnt > OrgHigh)
  1077.         Sect->Val =    AddrCnt;    /* End of old section */
  1078.     else
  1079.         Sect->Val =    OrgHigh;    /* We've ORGed higher */
  1080.     SectLine = LineCount;        /* Starting line number    */
  1081.     } else {
  1082.     SectLine = 1;            /* Start of first section */
  1083.     }
  1084.     AddrCnt = SectStart    = OrgHigh = 0L;    /* Reset location counter */
  1085.     OrgFlag = FALSE;
  1086.     TempAddr = StartAddr = AddrCnt;
  1087.     HunkType = (newflags & 0x3FFF0000L)    >> 16;    /* Type    */
  1088.     HunkFlags =    newflags & 0xC0000000L;        /* Flags */
  1089.     CurrHunk = NextHunk++;        /* Bump    next hunk number */
  1090.     newflags |=    CurrHunk;        /* Add hunk number */
  1091.     AddSymTab (tempop, 0L, newflags, LineCount,    16);    /* New entry */
  1092.     Sect = Sym;                /* Pointer to new entry    */
  1093.     MakeHunk = FALSE;            /* We don't have anything yet */
  1094.     if (AnyNear    && (CurrHunk > 1))
  1095.     Error (OpLoc, ManySect);    /* Too many hunks for small data */
  1096.     return;
  1097. }
  1098. SHAR_EOF
  1099. cat << \SHAR_EOF > Codegen.c
  1100. /*------------------------------------------------------------------*/
  1101. /*                                    */
  1102. /*              MC68000 Cross Assembler                */
  1103. /*                                    */
  1104. /*          Copyright    (c) 1985 by Brian R. Anderson            */
  1105. /*                                    */
  1106. /*          Object code generator - January 6, 1989            */
  1107. /*                                    */
  1108. /*   This program may be copied    for personal, non-commercial use    */
  1109. /*   only, provided that the above copyright notice is included        */
  1110. /*   on    all copies of the source code.    Copying    for any    other use   */
  1111. /*   without the consent of the    author is prohibited.            */
  1112. /*                                    */
  1113. /*------------------------------------------------------------------*/
  1114. /*                                    */
  1115. /*        Originally published (in Modula-2) in            */
  1116. /*        Dr.    Dobb's Journal, April, May, and June 1986.          */
  1117. /*                                    */
  1118. /*     AmigaDOS conversion copyright 1989 by Charlie Gibbs.        */
  1119. /*                                    */
  1120. /*------------------------------------------------------------------*/
  1121.  
  1122. #include <stdio.h>
  1123. #include "a68kdef.h"
  1124. #include "a68kglb.h"
  1125.  
  1126. /* Functions */
  1127. extern int  LineParts(), Instructions(), ObjDir();
  1128. extern int  GetInstModeSize(), GetMultReg(), CountNest();
  1129. extern int  ReadSymTab(), GetArgs(), GetAReg(),    OpenIncl();
  1130. extern long AddrBndW(),    AddrBndL(), GetValue(),    CalcValue();
  1131. extern char *AddName(),    *GetField();
  1132. extern struct SymTab *NextSym();
  1133. extern struct SymTab **HashIt();
  1134.  
  1135.  
  1136.  
  1137. GetObjectCode (dummy) int dummy;
  1138. /* Determines the object code for the operation    as well    as the operands    */
  1139. /* Returns each    (up to 3 fields), along    with the length    of each.     */
  1140. {
  1141.     int     quick;
  1142.     int     ExtL;        /* Bit pattern for instruction extension word */
  1143.     long templong;
  1144.     char tempop[MAXLINE];
  1145.     register int i, j;
  1146.  
  1147.     i =    Instructions (OpLoc);        /* Analyze the opcode */
  1148.  
  1149.     if (Dir != None) {
  1150.     ObjDir (dummy);            /* Process directives */
  1151.     return;
  1152.     }
  1153.     if ((Label[0] != '\0') || (OpCode[0] != '\0'))
  1154.     PrntAddr = TRUE;        /* Print address at least */
  1155.  
  1156.     if (OpCode[0] == '\0') {
  1157.     MakeHunk |= PrntAddr;
  1158.     return;                /* No op code, exit now    */
  1159.     }
  1160.     if (!i) {                /* Unrecognized    opcode */
  1161.     if ((Quiet < 0)    && (InF->UPtr == 0))
  1162.         ShowLine (InF->Line);    /* Show    where we are */
  1163.     if (OpCode[0] == '*') {
  1164.         Error (OpLoc, NoCode);    /* Don't try to open the console! */
  1165.         return;
  1166.     }
  1167.     if (Size == Byte)        /* Set up \0 parameter */
  1168.         MacSize[0] = 'B';
  1169.     else if    (Size == Long)
  1170.         MacSize[0] = 'L';
  1171.     else
  1172.         MacSize[0] = 'W';
  1173.  
  1174.     AddrAdv    = InstSize = 0;
  1175.     PrntAddr = FALSE;
  1176.     Dir = MacCall;            /* Assume it's a macro call */
  1177.     if (InF->UPtr == 0) {        /* If we're reading from a file */
  1178.         InF->Pos = lseek (In.fd, 0L,1); /*    remember where we are.    */
  1179.         InF->Pos -=    In.Lim - In.Ptr;
  1180.     }
  1181.     tempop[0] = ' ';
  1182.     tempop[1] = '\0';
  1183.     strcat (tempop,    OpCode);    /* Prepend a blank to OpCode */
  1184.     if (ReadSymTab (tempop)) {    /* Search for user macro */
  1185.         AddRef (LineCount);
  1186.         if(Sym->Defn < LineCount) {    /* Only    if previously defined! */
  1187.         InFNum++;
  1188.         if (--InF < LowInF)
  1189.             LowInF = InF;
  1190.         MacCount++;
  1191.         Heap2Space (0);            /* Check for space */
  1192.         InF->UPtr = (char *) Hunk2;    /* MACRO statement */
  1193.         InF->UPtr += strlen(InF->UPtr) + 1; /* Skip over it */
  1194.         InF->NPtr = NextFNS;    /* New stack pointer */
  1195.         InF->Line = 0;        /* Line    number in macro    */
  1196.         InF->NArg=GetArgs (""); /* Get arguments */
  1197.         InF->MCnt = MacCount;    /* Macro number    */
  1198.         if (OuterMac ==    0)
  1199.             OuterMac = InFNum;    /* Outer macro */
  1200.         return;
  1201.         }
  1202.     }
  1203.     if (!OpenIncl (OpCode, InclList)) {
  1204.         Error (OpLoc, NoCode);    /* Couldn't open file */
  1205.         Dir    = BadMac;        /* Invalid macro */
  1206.         if (InF->UPtr == 0)    {
  1207.         In.fd =    open (InF->NPtr, 0);
  1208.         lseek (In.fd, InF->Pos,    0);
  1209.         In.Ptr = In.Lim    = In.Buf;
  1210.         }
  1211.         return;            /* Return to outer file    */
  1212.     }
  1213.     InFNum++;            /* Bump    nesting    level */
  1214.     if (--InF < LowInF)
  1215.         LowInF = InF;
  1216.     MacCount++;
  1217.     Heap2Space (0);            /* Check for space */
  1218.     InF->UPtr = 0;            /* Not a user macro */
  1219.     InF->NPtr = NextFNS;        /* New stack pointer */
  1220.     InF->Line = 0;            /* Line    number in macro    */
  1221.     InF->NArg = GetArgs (OpCode);    /* Get arguments */
  1222.     InF->MCnt = MacCount;        /* Macro number    */
  1223.     if (OuterMac ==    0)
  1224.         OuterMac = InFNum;        /* Outer macro */
  1225.     return;
  1226.     }
  1227.  
  1228.     MakeHunk = TRUE;            /* We have something for a hunk    */
  1229.     AddrCnt = AddrBndW (AddrCnt);    /* It'll be word-aligned */
  1230.  
  1231.     if ((AdrModeA != 0)    || (AdrModeB !=    0)) {
  1232.     Src.Loc    = SrcLoc;
  1233.     Dest.Loc = DestLoc;
  1234.     GetOperand (SrcOp, &Src, SrcPC IN AdrModeB ? 2 : 0);
  1235.     GetOperand (DestOp, &Dest, EA05c IN AdrModeB ? 4 : 0);
  1236.     }
  1237.     if (EA05z IN AdrModeB) {        /* MOVEM */
  1238.     if ((Src.Mode != MultiM) && (Dest.Mode != MultiM)) {
  1239.         OpCode[4] =    '\0';           /* MOVEM of a single register */
  1240.         Instructions (OpLoc);    /*  becomes a straight MOVE   */
  1241.     }
  1242.     }
  1243.     if ((Src.Mode == Imm)        /* Immediate instructions */
  1244.     && (Src.Hunk == ABSHUNK) &&    (Src.Defn < LineCount)
  1245.     &&       (((EA611 IN AdrModeB) && (Dest.Mode == DReg)    /* MOVE    */
  1246.         && (Size ==    Long) && (Src.Value >= -128) &&    (Src.Value <= 127))
  1247.     || ((EA05y IN AdrModeB)                /* ADD/SUB */
  1248.         && (Src.Value > 0) && (Src.Value <=    8)))) {
  1249.         strcat (OpCode,    "Q");   /* Make it ADDQ/SUBQ/MOVEQ */
  1250.         Instructions (OpLoc);
  1251.     }
  1252.     else if ((Dest.Mode    == ARDir) && (Src.Mode <= 12)
  1253.     && (((EA05y    | EA611) IN AdrModeB)    /* ADD,    SUB, or    MOVE */
  1254.     || (OpM68C IN AdrModeA))) {    /* CMP */
  1255.         strcat (OpCode, "A");       /* ADD op,An becomes ADDA etc. */
  1256.         Instructions (OpLoc);
  1257.     }
  1258.     else if ((Src.Mode == Imm)        /* Immediate instructions */
  1259.     && ((OpM68D    | OpM68C | OpM68X) IN AdrModeA)) {
  1260.     strcat (OpCode,    "I");           /* ADD/AND/OR/SUB, CMP, EOR */
  1261.     Instructions (OpLoc);        /* ADD #op,d becomes ADDI etc. */
  1262.     }
  1263.     else if ((Src.Mode == ARPost) && (Dest.Mode    == ARPost)
  1264.     && (OpM68C IN AdrModeA)) {        /* CMP */
  1265.     strcat (OpCode,    "M");           /* Generate CMPM if necessary */
  1266.     Instructions (OpLoc);
  1267.     }
  1268.  
  1269.  
  1270. /*=================== Operand validation routines ====================*/
  1271.  
  1272.     if (Pass2) {
  1273.  
  1274.     /* If an immediate operand isn't absolute, it must be a long word */
  1275.  
  1276.     if ((Src.Mode == Imm) && (Size != Long)    && (Src.Hunk !=    ABSHUNK))
  1277.         Error (SrcLoc, RelErr);
  1278.  
  1279.     /* ------- Check for instructions with too many operands. ------- */
  1280.     /* Some specialized    instruction routines contain their own tests. */
  1281.  
  1282.     if (AdrModeA ==    0) {        /* Should have only one    operand    */
  1283.         if ((AdrModeB == EA05e) || (AdrModeB == (Size67 | EA05e))) {
  1284.         if (Dest.Mode != Null)
  1285.             Error (DestLoc, OperErr);
  1286. /*        } else if (AdrModeB    == 0) {    */  /* Should have no operands */
  1287. /*        if (Src.Mode !=    Null)
  1288.             Error (SrcLoc, OperErr);
  1289.         if (Dest.Mode != Null)
  1290.             Error (DestLoc, OperErr); De-activated for now */
  1291.         }
  1292.     }
  1293.     if ((AdrModeA != 0) || (AdrModeB != 0))    {
  1294.         if(Dest.Mode != NULL) { /* We should never find 3 operands */
  1295.         j = DestLoc + strlen (DestOp);
  1296.         if ((Line[j] !=    '\0')
  1297.         && (Line[j] != ';')
  1298.         && (!isspace (Line[j]))) {
  1299.             Error (j, OperErr);
  1300.         }
  1301.         }
  1302.  
  1303.     /* ----------------    Check for missing operands. ----------------- */
  1304.  
  1305.         if (Src.Mode == Null) {
  1306.         Error (OpLoc+strlen(OpCode), OperErr);    /* No source */
  1307.         } else if (Dest.Mode == Null) {
  1308.         if (((ImmMode &    AdrModeB) == ImmMode)
  1309.         || (TwoOpsA IN AdrModeA)
  1310.         || (TwoOpsB IN AdrModeB)) {
  1311.             Error (SrcLoc+strlen(SrcOp), OperErr);  /* No dest.    */
  1312.         }
  1313.         }
  1314.     }
  1315.     }
  1316.  
  1317. /*====================================================================*/
  1318.  
  1319.     /* ----------------    Decrement and Branch (DBcc) ----------------- */
  1320.  
  1321.     if (DecBr IN AdrModeA) {
  1322.     if (Pass2) {
  1323.         if (Src.Mode != DReg)
  1324.         Error (SrcLoc, ModeErr);
  1325.         if (Dest.Value & 1)
  1326.         Error (DestLoc,    AlignErr);  /* Boundary    alignment error    */
  1327.  
  1328.         if (Dest.Hunk == CurrHunk) {
  1329.         ObjSrc = Dest.Value-AddrCnt-2;    /* Relative branch distance */
  1330.         Dest.Hunk = ABSHUNK;        /* Displacement    is absolute */
  1331.         } else
  1332.         ObjSrc = 0;        /* Let the linker worry    about it */
  1333.  
  1334.         if ((ObjSrc    > 32767) || (ObjSrc < -32768))
  1335.         Error (DestLoc,BraErr);    /* Too far to branch */
  1336.  
  1337.         if (Dest.Hunk!=CurrHunk) {    /* DBcc    to another section */
  1338.         templong = AddrCnt + 2;    /* 16-bit relocatable */
  1339.         PutRel (templong, Dest.Hunk, 2);
  1340.         }
  1341.         ObjOp = Op | Src.Rn;
  1342.     }
  1343.     AddrAdv    = 4;
  1344.     nO = nS    = 2;
  1345.     return;
  1346.     }
  1347.  
  1348.     /* ------------ Branch (Bcc, including BRA and BSR)    ------------- */
  1349.  
  1350.     if (Brnch IN AdrModeA) {
  1351.     if (Src.Value &    1)
  1352.         Error (SrcLoc, AlignErr);    /* Boundary alignment error */
  1353.  
  1354.     if (Src.Hunk ==    CurrHunk) {
  1355.         ObjSrc=Src.Value-AddrCnt-2;    /* Relative branch distance */
  1356.         Src.Hunk = ABSHUNK;        /* Displacement    is absolute */
  1357.         if (Size !=    Byte) {
  1358.         if ((ObjSrc >= -128) &&    (ObjSrc    <= 127)    && (ObjSrc != 0))
  1359.             if (DefLine2 < LineCount)
  1360.             Size = Byte;    /* Short branch    if possible */
  1361.             else if (Pass2 && FwdProc && (Size != Byte))
  1362.             FwdShort=TRUE;    /* Fwd.    ref. could be made short */
  1363.         }
  1364.         if ((Size == Byte) && (ObjSrc == 0))
  1365.         Error (SrcLoc, BccSDsp0);    /* Can't do this! */
  1366.     } else {
  1367.         ObjSrc = 0;            /* Let the linker worry    about it */
  1368.         if (Size ==    Byte)
  1369.         Error (SrcLoc, BraErr);    /* No external short branches! */
  1370.     }
  1371.  
  1372.     if (Size != Byte) {
  1373.         InstSize = 4;
  1374.         nS = 2;
  1375.         templong = 32767;
  1376.     } else {
  1377.         InstSize = 2;
  1378.         Op |= (ObjSrc & 0x00FF);
  1379.         templong = 127;
  1380.     }
  1381.     if ((ObjSrc > templong)    || (ObjSrc < -templong-1))
  1382.         Error (SrcLoc, BraErr);    /* Too far to branch */
  1383.  
  1384.     if (Dest.Mode != Null)
  1385.         Error (DestLoc, OperErr);    /* No Destination operand! */
  1386.  
  1387.     AddrAdv    = InstSize;
  1388.     ObjOp =    Op;
  1389.     nO = 2;
  1390.     if (Src.Hunk !=    CurrHunk) {    /* Bcc to another section */
  1391.         templong = AddrCnt + 2;    /* 16-bit relocatable */
  1392.         PutRel (templong, Src.Hunk,    2);
  1393.     }
  1394.     return;
  1395.     }
  1396.  
  1397.     /* ------------ Check for short (16-bit) JMP or JSR    ------------- */
  1398.  
  1399.     if ((Op == JMP) || (Op == JSR))
  1400.     if ((Size == Byte) && (Src.Mode    == AbsL))
  1401.         Src.Mode = AbsW;
  1402.  
  1403. /*  Uses information from Instructions & GetOperand (among others)  */
  1404. /*  to complete    calculation of Object Code.                */
  1405. /*  Op,    AdrModeA, AdrModeB, Size, and Src & Dest records are all    */
  1406. /*  Global variables imported from the SyntaxAnalyzer MODULE.        */
  1407.  
  1408.     ExtL = 0;
  1409.     quick = FALSE;
  1410.  
  1411.     /* ------------ Check for boundary alignment errors. ------------ */
  1412.     /*    BCHG, BCLR, BSET, BTST,    LEA, NBCD, PEA,    Scc, TAS are exempt.  */
  1413.  
  1414.     if (Pass2) {
  1415.     if ((Size != Byte)
  1416.     && (Op != LEA)
  1417.     && (Op != PEA)
  1418.     && !((AdrModeA == 0) &&    (AdrModeB == 0))
  1419.     && !(AdrModeB &    EA05c)        /* BTST */
  1420.     && !((AdrModeB&EA05e) && (AdrModeA==0) && !(AdrModeB&Size67))) {
  1421.         if (Src.Value & 1)
  1422.         if ((Src.Mode >= ARDisp) && (Src.Mode <= PCDisX))
  1423.             Error (SrcLoc, AlignErr);
  1424.         if (Dest.Value & 1)
  1425.         if ((Dest.Mode >= ARDisp) && (Dest.Mode    <= PCDisX))
  1426.             Error (DestLoc, AlignErr);
  1427.     }
  1428.  
  1429. /* Check for 5 special cases first */
  1430.  
  1431.     if (Op == STOP)    {
  1432.         if (Src.Mode != Imm)
  1433.         Error (SrcLoc, OperErr);
  1434.         if (Dest.Mode != Null)
  1435.         Error (DestLoc,    OperErr);
  1436.     }
  1437.  
  1438.     if (Op == LINK)    {
  1439.         Op |= Src.Rn;
  1440.         if (Src.Mode != ARDir)
  1441.         Error (SrcLoc, ModeErr);
  1442.         if (Dest.Mode != Imm)
  1443.         Error (DestLoc,    ModeErr);
  1444.         else if (Dest.Value    & 1)
  1445.         Error (DestLoc,    AlignErr);  /* Boundary    alignment error    */
  1446.     }
  1447.  
  1448.     if (Op == SWAP)    {
  1449.         if (!(EA05f    IN AdrModeB)) {    /* Ignore if PEA instruction */
  1450.         Op |= Src.Rn;
  1451.         if (Src.Mode !=    DReg)
  1452.             Error (SrcLoc, OperErr);
  1453.         if (Dest.Mode != Null)
  1454.             Error (DestLoc, OperErr);
  1455.         }
  1456.     }
  1457.  
  1458.     if (Op == UNLK)    {
  1459.         Op |= Src.Rn;
  1460.         if (Src.Mode != ARDir)
  1461.         Error (SrcLoc, OperErr);
  1462.         if (Dest.Mode != Null)
  1463.         Error (DestLoc,    OperErr);
  1464.     }
  1465.  
  1466. /* Now do generalized address modes */
  1467.  
  1468.     if ((Ry02 IN AdrModeA)&&(Rx911 IN AdrModeA)) {    /* 2 registers */
  1469.         if (Op == CMPM) {        /* Special routine for CMPM */
  1470.         Op |= Src.Rn | (Dest.Rn    << 9);
  1471.         if (Src.Mode !=    ARPost)
  1472.             Error (SrcLoc, ModeErr);
  1473.         if (Dest.Mode != ARPost)
  1474.             Error (DestLoc, ModeErr);
  1475.         } else {        /* Other two-register instructions */
  1476.         Op |= Src.Rn | (Dest.Rn    << 9);
  1477.         if (RegMem3 IN AdrModeA) {
  1478.             if (Src.Mode == DReg) {
  1479.             if (Dest.Mode != DReg)
  1480.                 Error (DestLoc, ModeErr);
  1481.             } else if (Src.Mode    == ARPre) {
  1482.             Op |= 0x0008;
  1483.             if (Dest.Mode != ARPre)
  1484.                 Error (DestLoc, ModeErr);
  1485.             } else
  1486.             Error (SrcLoc, OperErr);
  1487.         } else {
  1488.             if (Src.Mode == ARPost)
  1489.             if (Dest.Mode != ARPost)
  1490.                 Error (DestLoc, ModeErr);
  1491.             else
  1492.                 Error (SrcLoc, OperErr);
  1493.         }
  1494.         }
  1495.     }
  1496.     }
  1497.     if (Data911    IN AdrModeA) {        /* Data    in 9-11    (ADDQ/SUBQ) */
  1498.     quick =    TRUE;
  1499.     if (Src.Mode ==    Imm)
  1500.         if ((Src.Value > 0)    && (Src.Value <= 8)) {
  1501.         if (Src.Value <    8)  /* Data of 8 is coded as 000 */
  1502.             Op |= Src.Value << 9;
  1503.         } else
  1504.         Error (SrcLoc, SizeErr);
  1505.     else
  1506.         Error (SrcLoc, OperErr);
  1507.     }
  1508.  
  1509.     if (CntR911    IN AdrModeA) {        /* Only    Shift/Rotate use this */
  1510.     if (Dest.Mode == DReg) {
  1511.         Op = (Op & 0xF9FF) | Dest.Rn;
  1512.         if (Size ==    Word) Op |= 0x0040;
  1513.         if (Size ==    Long) Op |= 0x0080;
  1514.         if (Src.Mode == DReg)
  1515.         Op |= 0x0020 | (Src.Rn << 9);
  1516.         else if (Src.Mode == Imm) {
  1517.         quick =    TRUE;
  1518.         /* Range Check */
  1519.         if ((Src.Value > 0) && (Src.Value <= 8)) {
  1520.             if (Src.Value < 8) /* Data of 8 is coded as    000 */
  1521.             Op |= (Src.Value << 9);
  1522.         } else
  1523.             Error (SrcLoc, SizeErr);
  1524.         } else
  1525.         Error (SrcLoc, OperErr);
  1526.     } else if (Dest.Mode ==    Null) {
  1527.         Op = (Op & 0xFFE7) | 0x00C0;
  1528.         EffAdr (&Src, (mea | aea));
  1529.     } else
  1530.         Error (SrcLoc, OperErr);
  1531.     }
  1532.  
  1533.     if (Data03 IN AdrModeA) {        /* TRAP    Vector in 0-3 */
  1534.     quick =    TRUE;
  1535.     if (Src.Mode ==    Imm)
  1536.         if ((Src.Value >= 0) && (Src.Value < 16))
  1537.         Op |= Src.Value;
  1538.         else
  1539.         Error (SrcLoc, SizeErr);
  1540.     else
  1541.         Error (SrcLoc, OperErr);
  1542.  
  1543.     if (Dest.Mode != Null)
  1544.         Error (DestLoc, OperErr);
  1545.     }
  1546.  
  1547.     if (Data07 IN AdrModeA) {        /* Data    in 0-7 (MOVEQ) */
  1548.     quick =    TRUE;
  1549.     Op |= (Src.Value & 0x00FFL) | (Dest.Rn << 9);
  1550.     if (Src.Mode !=    Imm)
  1551.         Error (SrcLoc, ModeErr);
  1552.     else if    (Dest.Mode != DReg)
  1553.         Error (DestLoc, ModeErr);
  1554.     else if    ((Src.Value < -128) || (Src.Value > 127))
  1555.         Error (SrcLoc, SizeErr);
  1556.     }
  1557.  
  1558.     if (Pass2) {
  1559.     if (OpM68D IN AdrModeA)    {   /* DReg in 6-8 (ADD/AND/OR/SUB) */
  1560.         if (Dest.Mode == DReg) {
  1561.         Op |= (Dest.Rn << 9);
  1562.         if ((Src.Mode == ARDir)    && (Size == Byte))
  1563.             Error (SrcLoc, SizeErr);
  1564.         } else /* Assume Src.Mode =    DReg --    Error trapped elsewhere    */
  1565.         Op |= (Src.Rn << 9) | 0x0100;
  1566.  
  1567.         if (Size ==    Word) Op |= 0x0040;
  1568.         if (Size ==    Long) Op |= 0x0080;
  1569.     }
  1570.  
  1571.     if (OpM68A IN AdrModeA)    {   /* AReg in 6-8 (ADDA/CMPA/SUBA) */
  1572.         if (Dest.Mode == ARDir)
  1573.         Op |= (Dest.Rn << 9);
  1574.         else
  1575.         Error (DestLoc,    ModeErr);
  1576.  
  1577.         if (Size ==    Byte) Error (OpLoc+5, SizeErr);
  1578.         if (Size ==    Word) Op |= 0x00C0;
  1579.         if (Size ==    Long) Op |= 0x01C0;
  1580.     }
  1581.  
  1582.     if (OpM68C IN AdrModeA)    {    /* CMP (Compare) */
  1583.         if (Dest.Mode == DReg)
  1584.         Op |= (Dest.Rn << 9);
  1585.         else
  1586.         Error (DestLoc,    ModeErr);
  1587.  
  1588.         if (Size ==    Byte) {
  1589.         if (Src.Mode ==    ARDir)
  1590.             Error (OpLoc+4, SizeErr);
  1591.         }
  1592.         if (Size ==    Word) Op |= 0x0040;
  1593.         if (Size ==    Long) Op |= 0x0080;
  1594.     }
  1595.  
  1596.     if (OpM68X IN AdrModeA)    {    /* EOR (Exclusive or) */
  1597.         if (Src.Mode == DReg)
  1598.         Op |= (Src.Rn << 9);
  1599.         else
  1600.         Error (SrcLoc, ModeErr);
  1601.  
  1602.         if (Size ==    Byte) Op |= 0x0100;
  1603.         if (Size ==    Word) Op |= 0x0140;
  1604.         if (Size ==    Long) Op |= 0x0180;
  1605.     }
  1606.  
  1607.     if (OpM68S IN AdrModeA)    {    /* EXT (Sign extension)    */
  1608.         if (Src.Mode == DReg)
  1609.         Op |= Src.Rn;
  1610.         else
  1611.         Error (SrcLoc, ModeErr);
  1612.  
  1613.         if (Dest.Mode != Null)
  1614.         Error (DestLoc,    OperErr);
  1615.  
  1616.         if (Size ==    Byte) Error (OpLoc+4, SizeErr);
  1617.         if (Size ==    Word) Op |= 0x0080;
  1618.         if (Size ==    Long) Op |= 0x00C0;
  1619.     }
  1620.  
  1621.     if (OpM68R IN AdrModeA)    {    /* MOVEP (Register/memory) */
  1622.         if ((Src.Mode == DReg) && (Dest.Mode == ARDisp)) {
  1623.         if (Size == Byte) Error    (OpLoc+6, SizeErr);
  1624.         if (Size == Word) Op |=    0x0180;
  1625.         if (Size == Long) Op |=    0x01C0;
  1626.         Op |= (Src.Rn << 9) | Dest.Rn;
  1627.         } else if ((Src.Mode == ARDisp) && (Dest.Mode == DReg)) {
  1628.         if (Size == Byte) Error    (OpLoc+6, SizeErr);
  1629.         if (Size == Word) Op |=    0x0100;
  1630.         if (Size == Long) Op |=    0x0140;
  1631.         Op |= Src.Rn | (Dest.Rn    << 9);
  1632.         } else
  1633.         Error (SrcLoc, ModeErr);
  1634.     }
  1635.  
  1636.     if (OpM37 IN AdrModeA) {    /* EXG (Exchange registers) */
  1637.         if ((Src.Mode == DReg) && (Dest.Mode == DReg))
  1638.         Op |= 0x0040 | (Src.Rn << 9) | Dest.Rn;
  1639.         else if ((Src.Mode == ARDir) && (Dest.Mode == ARDir))
  1640.         Op |= 0x0048 | (Src.Rn << 9) | Dest.Rn;
  1641.         else if ((Src.Mode == ARDir) && (Dest.Mode == DReg))
  1642.         Op |= 0x0088 | (Dest.Rn    << 9) |    Src.Rn;
  1643.         else if ((Src.Mode == DReg)    && (Dest.Mode == ARDir))
  1644.         Op |= 0x0088 | (Src.Rn << 9) | Dest.Rn;
  1645.         else
  1646.         Error (SrcLoc, ModeErr);
  1647.     }
  1648.  
  1649.     if (Bit811 IN AdrModeB)    {   /* Bit operations using bits 8-11 */
  1650.         Size = Word;        /* Ignore size specification */
  1651.         if (Src.Mode == DReg)
  1652.         Op |= 0x0100 | (Src.Rn << 9);
  1653.         else if (Src.Mode == Imm)
  1654.         Op |= 0x0800;
  1655.         else
  1656.         Error (SrcLoc, ModeErr);
  1657.     }
  1658.  
  1659.     if (Size67 IN AdrModeB)    {    /* Size    in bits    6-7 */
  1660.      /* if (Size ==    Byte) ;    No action -- bits are already 0    */
  1661.         if (Size ==    Word) Op |= 0x0040;
  1662.         if (Size ==    Long) Op |= 0x0080;
  1663.     }
  1664.  
  1665.     if (Size6 IN AdrModeB) {    /* Size    in bit 6 (MOVEM) */
  1666.         if (Size ==    Byte) Error (OpLoc+6, SizeErr);
  1667.      /* if (Size ==    Word) ;    No Action -- bit is already 0 */
  1668.         if (Size ==    Long) Op |= 0x0040;
  1669.     }
  1670.  
  1671.     if (Sz1213A IN AdrModeB) {    /* Size    in 12-13 (MOVE)    */
  1672.         if (Size ==    Byte) Op |= 0x1000;
  1673.         if (Size ==    Word) Op |= 0x3000;
  1674.         if (Size ==    Long) Op |= 0x2000;
  1675.     }
  1676.  
  1677.     if (Sz1213 IN AdrModeB)    {    /* Size    in 12-13 (MOVEA) */
  1678.         if (Dest.Mode == DReg)    /* Can't be to data register! */
  1679.         Error(DestLoc,ModeErr);    /* (Others are caught elsewhere) */
  1680.         Op |= (Dest.Rn << 9);
  1681.         if (Size ==    Byte) Error (OpLoc+6, SizeErr);
  1682.         if (Size ==    Word) Op |= 0x3000;
  1683.         if (Size ==    Long) Op |= 0x2000;
  1684.     }
  1685.  
  1686.     if (EA05a IN AdrModeB)        /* Effective address - all */
  1687.         if ((Dest.Mode == DReg) || (Dest.Mode == ARDir))
  1688.         EffAdr (&Src, ea);
  1689.         else
  1690.         Error (DestLoc,    ModeErr);
  1691.  
  1692.     if (EA05b IN AdrModeB)    /* Eff.    Addr. -    all except ARDir */
  1693.         if (Dest.Mode == DReg) {
  1694.         EffAdr (&Src, dea);
  1695.         Op |= (Dest.Rn << 9);
  1696.         } else
  1697.         Error (DestLoc,    ModeErr);
  1698.  
  1699.     if (EA05c IN AdrModeB)        /* BTST    */
  1700.         EffAdr (&Dest, 0x0802);    /* All but ARDir/Imm */
  1701.  
  1702.     if(EA05d IN AdrModeB) {    /* All but PC relative & immediate */
  1703.         EffAdr (&Dest, aea);
  1704.         if ((Dest.Mode == ARDir) &&    (Size == Byte))
  1705.         Error (OpLoc+5,    SizeErr);
  1706.     }
  1707.  
  1708.     if(EA05e IN AdrModeB) {    /* All but ARDir, PC relative, Imm */
  1709.         if (Dest.Mode == Null)
  1710.         EffAdr (&Src, (dea | aea));
  1711.         else if ((Src.Mode == Imm) || (Src.Mode == DReg))
  1712.         EffAdr (&Dest, (dea | aea));
  1713.         else
  1714.         Error (SrcLoc, ModeErr);
  1715.     }
  1716.  
  1717.     if (EA05f IN AdrModeB) {    /* JMP,    JSR, LEA, and PEA */
  1718.         EffAdr (&Src, cea);
  1719.         if (Rx911 IN AdrModeA)
  1720.         if (Dest.Mode == ARDir)
  1721.             Op |= (Dest.Rn << 9);   /* Address Reg. for    LEA */
  1722.         else
  1723.             Error(DestLoc,ModeErr); /* Must load Address Reg. */
  1724.         else
  1725.         if (Dest.Mode != Null)
  1726.             Error (DestLoc, OperErr);    /* No Dest. unless LEA */
  1727.     }
  1728.  
  1729.     if (EA05x IN AdrModeB) {    /* AND and OR */
  1730.         if (Dest.Mode == DReg)
  1731.         EffAdr (&Src, dea);
  1732.         else if (Src.Mode == DReg)
  1733.         EffAdr (&Dest, mea | aea);
  1734.         else
  1735.         Error (SrcLoc, OperErr);
  1736.     }
  1737.  
  1738.     if (EA05y IN AdrModeB) {    /* ADD and SUB */
  1739.         if (Dest.Mode == DReg) {
  1740.         EffAdr (&Src, ea);
  1741.         if ((Src.Mode == ARDir)    && (Size == Byte))
  1742.             Error (OpLoc+4, SizeErr);
  1743.         } else if (Src.Mode    == DReg)
  1744.         EffAdr (&Dest, (mea | aea));
  1745.         else
  1746.         Error (SrcLoc, ModeErr);
  1747.     }
  1748.     }
  1749.  
  1750.     if (EA05z IN AdrModeB) {        /* MOVEM */
  1751.     if (Pass2) {
  1752.         if (Src.Mode == MultiM) {        /* Move    to memory */
  1753.         EffAdr (&Dest, (mea | aea | 0x0008));
  1754.         ExtL = Src.Value;
  1755.         i = (Dest.Mode == ARPre);    /* ExtL    flip indicator */
  1756.         } else if (Dest.Mode == MultiM) {    /* Move    from memory */
  1757.         Op |= 0x0400;            /* Set direction */
  1758.         EffAdr (&Src, (mea | 0x0810));
  1759.         ExtL = Dest.Value;
  1760.         i = (Src.Mode == ARPre);
  1761.         } else {
  1762.         Error (SrcLoc, OperErr);
  1763.         i = FALSE;
  1764.         }
  1765.         if (i) {                /* Flip    ExtL if    ARPre */
  1766.         j = 0;
  1767.         for (i = 0; i <    8; i++)
  1768.             j |= (ExtL & (1<<i)) << (15-i*2);
  1769.         for (i = 8; i <    16; i++)
  1770.             j |= (ExtL & (1<<i)) >> (i*2-15);
  1771.         ExtL = j;
  1772.         }
  1773.     }
  1774.     nO += 2;    /* Extension is    part of    OpCode */
  1775.     InstSize += 2;
  1776.     }
  1777.  
  1778.     if (Pass2) {
  1779.  
  1780.     if (EA611 IN AdrModeB) {    /* Eff.    Addr. in 6-11 (MOVE) */
  1781.         if (Dest.Mode == CCR) {        /* MOVE    to CCR */
  1782.         Op = 0x44C0;
  1783.         EffAdr (&Src, dea);
  1784.         } else if (Dest.Mode == SR)    {    /* MOVE    to SR */
  1785.         Op = 0x46C0;
  1786.         EffAdr (&Src, dea);
  1787.         } else if (Src.Mode    == SR) {    /* MOVE    from SR    */
  1788.         Op = 0x40C0;
  1789.         EffAdr (&Dest, dea | aea);
  1790.         } else if (Dest.Mode == USP) {    /* MOVE    to USP */
  1791.         Op = 0x4E60;
  1792.         if (Src.Mode ==    ARDir)
  1793.             Op |= Src.Rn;
  1794.         else
  1795.             Error (SrcLoc, ModeErr);
  1796.         } else if (Src.Mode    == USP)    {    /* MOVE    from USP */
  1797.         Op = 0x4E68;
  1798.         if (Dest.Mode == ARDir)
  1799.             Op |= Dest.Rn;
  1800.         else
  1801.             Error (DestLoc, ModeErr);
  1802.         } else {            /* General MOVE    instruction */
  1803.         EffAdr (&Src, (ea | xxx));
  1804.         if ((Size == Byte) && (Src.Mode    == ARDir))
  1805.             Error (SrcLoc, SizeErr);
  1806.         if (Src.Mode > 12)
  1807.             Error (SrcLoc, ModeErr);
  1808.         if (((1<<(Dest.Mode-1))    IN (dea|aea)) || (Dest.Mode>12))
  1809.             Error (DestLoc, ModeErr);
  1810.         else if    (Dest.Mode < 8)    /* Register direct or indirect */
  1811.             Op |= ((Dest.Mode -    1) << 6) | (Dest.Rn << 9);
  1812.         else        /* Absolute, PC    relative, or immediate */
  1813.             Op |= 0x01C0 | ((Dest.Mode - 8) << 9);
  1814.         OperExt    (&Dest);        /* Set up extension    word */
  1815.         }
  1816.     }
  1817.  
  1818.     if ((Dest.Mode == CCR) && (Src.Mode == Imm)) {
  1819.         if ((Size67    IN AdrModeB)
  1820.         && (EA05e IN AdrModeB)
  1821.         && (Exten IN AdrModeB))
  1822.         if (0x0400 IN Op)    /* not ANDI/EORI/ORI */
  1823.             Error (DestLoc, ModeErr);
  1824.         else
  1825.             Op = (Op & 0xFF00) | 0x003C;
  1826.     }
  1827.  
  1828.     if ((Dest.Mode == SR) && (Src.Mode == Imm)) {
  1829.         if ((Size67    IN AdrModeB)
  1830.         && (EA05e IN AdrModeB)
  1831.         && (Exten IN AdrModeB))
  1832.         if (0x0400 IN Op)    /* not ANDI/EORI/ORI */
  1833.             Error (DestLoc, ModeErr);
  1834.         else
  1835.             Op = (Op & 0xFF00) | 0x007C;
  1836.     }
  1837.     }
  1838.  
  1839.     ObjOp = Op;
  1840.     InstSize +=    2;
  1841.     nO += 2;
  1842.     if (nO > 2)    {
  1843.     templong = ExtL;            /* Add extension word */
  1844.     ObjOp =    (ObjOp << 16) |    (templong & 0x0000FFFFL);
  1845.     }
  1846.     if ((AdrModeA != 0)    || (AdrModeB !=    0)) {
  1847.     InstSize += (nS    = GetInstModeSize (Src.Mode));
  1848.     ObjSrc = Src.Value;
  1849.     InstSize += (nD    = GetInstModeSize (Dest.Mode));
  1850.     ObjDest    = Dest.Value;
  1851.     }
  1852.     if (quick) {
  1853.     InstSize -= nS;        /* Source operand is in    Op */
  1854.     nS = 0;
  1855.     }
  1856.  
  1857.     if (Pass2) {
  1858.     if ((nS!=0) && (Src.Hunk!=ABSHUNK)) {    /* SrcOp relocatable */
  1859.         if ((Src.Mode == AbsL)
  1860.         || (Src.Mode == AbsW)
  1861.         || (Src.Mode == ARDisp)
  1862.         || (Src.Mode == PCDisp)
  1863.         || (Src.Mode == Imm)) {
  1864.         templong = AddrCnt+nO;    /* 32- or 16-bit relocatable */
  1865.         PutRel (templong, Src.Hunk, nS);
  1866.         }
  1867.         if ((Src.Mode==ARDisX) || (Src.Mode==PCDisX)) {
  1868.         templong = AddrCnt + nO    + 1;    /* 8-bit relocatable */
  1869.         PutRel (templong, Src.Hunk, 1);
  1870.         }
  1871.     }
  1872.     if ((nD!=0) && (Dest.Hunk!=ABSHUNK)) {    /* DestOp relocatable */
  1873.         if ((Dest.Mode == AbsL)
  1874.         || (Dest.Mode == AbsW)
  1875.         || (Dest.Mode == ARDisp)
  1876.         || (Dest.Mode == PCDisp)
  1877.         || (Dest.Mode == Imm)) {
  1878.         templong = AddrCnt+nO+nS; /* 32- or 16-bit relocatable */
  1879.         PutRel (templong, Dest.Hunk, nD);
  1880.         }
  1881.         if ((Dest.Mode==ARDisX) || (Dest.Mode==PCDisX)) {
  1882.         templong = AddrCnt+nO+nS+1;    /* 8-bit relocatable */
  1883.         PutRel (templong, Dest.Hunk, 1);
  1884.         }
  1885.     }
  1886.     }
  1887.     AddrAdv = InstSize;
  1888. }
  1889. SHAR_EOF
  1890. cat << \SHAR_EOF > Opcodes.c
  1891. /*------------------------------------------------------------------*/
  1892. /*                                    */
  1893. /*              MC68000 Cross Assembler                */
  1894. /*                                    */
  1895. /*          Copyright    (c) 1985 by Brian R. Anderson            */
  1896. /*                                    */
  1897. /*       Opcode table    and scan routine - January 6, 1989        */
  1898. /*                                    */
  1899. /*   This program may be copied    for personal, non-commercial use    */
  1900. /*   only, provided that the above copyright notice is included        */
  1901. /*   on    all copies of the source code.    Copying    for any    other use   */
  1902. /*   without the consent of the    author is prohibited.            */
  1903. /*                                    */
  1904. /*------------------------------------------------------------------*/
  1905. /*                                    */
  1906. /*        Originally published (in Modula-2) in            */
  1907. /*        Dr.    Dobb's Journal, April, May, and June 1986.          */
  1908. /*                                    */
  1909. /*     AmigaDOS conversion copyright 1989 by Charlie Gibbs.        */
  1910. /*                                    */
  1911. /*------------------------------------------------------------------*/
  1912.  
  1913. #include <stdio.h>
  1914. #include "a68kdef.h"
  1915. #include "a68kglb.h"
  1916.  
  1917. /* Functions */
  1918. extern int  LineParts(), ObjDir();
  1919. extern int  GetInstModeSize(), GetMultReg(), CountNest();
  1920. extern int  ReadSymTab(), GetArgs(), GetAReg(),    OpenIncl();
  1921. extern long AddrBndW(),    AddrBndL(), GetValue(),    CalcValue();
  1922. extern char *AddName(),    *GetField();
  1923. extern struct SymTab *NextSym();
  1924. extern struct SymTab **HashIt();
  1925.  
  1926.  
  1927.  
  1928. int Instructions (loc) int loc;
  1929. /* Looks up opcode and addressing mode bit patterns
  1930.    If the opcode corresponds to    an executable instruction,
  1931.      returns TRUE with the following fields set    up:
  1932.     Op     - operation code bits
  1933.     AdrModeA - addressing mode bits
  1934.     AdrModeB - more    addressing mode    bits
  1935.     Dir     - None
  1936.    If the opcode corresponds to    a directive (AdrModeA in the table
  1937.      is    0xFFFF), returns TRUE with the following fields    set up:
  1938.     Op     - 0
  1939.     AdrModeA - 0
  1940.     AdrModeB - 0
  1941.     Dir     - the appropriate directive value
  1942.    If not found, returns FALSE with all    the above fields set to    zero.
  1943.  
  1944.    NOTE: The binary search doesn't use strcmp because this function
  1945.     returns incorrect values under MS-DOS Lattice 2.12.              */
  1946. {
  1947.     static int maxinst = 0;        /* Size    of opcode table    */
  1948.     static int limits['Z'-'A'+2];       /* Table limits by first letter */
  1949.     register char *i, *j;
  1950.     register int  lower, upper,    mid;    /* Binary search controls */
  1951.  
  1952. /* Opcode table    */
  1953.  
  1954.     struct OpTab {
  1955.     char Mnem[8];    /* Instruction mnemonic    */
  1956.     int  OpBits;    /* Op code bits    */
  1957.     int  AMA;    /* Address mode    bits */
  1958.     int  AMB;    /* More    address    mode bits */
  1959.     };
  1960.  
  1961.     static struct OpTab    MnemTab[] = {
  1962.     "=",     0,      0xFFFF, Equ,
  1963.     "ABCD",  0xC100, Rx911 | RegMem3 | Ry02, 0,
  1964.     "ADD",   0xD000, OpM68D, EA05y,
  1965.     "ADDA",  0xD000, OpM68A, EA05a,
  1966.     "ADDI",  0x0600, 0, Size67 | EA05e | Exten,
  1967.     "ADDQ",  0x5000, Data911, Size67 | EA05d,
  1968.     "ADDX",  0xD100, Rx911 | RegMem3 | Ry02, Size67,
  1969.     "AND",   0xC000, OpM68D, EA05x,
  1970.     "ANDI",  0x0200, 0, Size67 | EA05e | Exten,
  1971.     "ASL",   0xE100, CntR911, 0,
  1972.     "ASR",   0xE000, CntR911, 0,
  1973.     "BCC",   0x6400, Brnch, 0,
  1974.     "BCHG",  0x0040, 0, EA05e | Exten | Bit811,
  1975.     "BCLR",  0x0080, 0, EA05e | Exten | Bit811,
  1976.     "BCS",   0x6500, Brnch, 0,
  1977.     "BEQ",   0x6700, Brnch, 0,
  1978.     "BGE",   0x6C00, Brnch, 0,
  1979.     "BGT",   0x6E00, Brnch, 0,
  1980.     "BHI",   0x6200, Brnch, 0,
  1981.     "BLE",   0x6F00, Brnch, 0,
  1982.     "BLS",   0x6300, Brnch, 0,
  1983.     "BLT",   0x6D00, Brnch, 0,
  1984.     "BMI",   0x6B00, Brnch, 0,
  1985.     "BNE",   0x6600, Brnch, 0,
  1986.     "BPL",   0x6A00, Brnch, 0,
  1987.     "BRA",   0x6000, Brnch, 0,
  1988.     "BSET",  0x00C0, 0, EA05e | Exten | Bit811,
  1989.     "BSR",   0x6100, Brnch, 0,
  1990.     "BSS",   0,      0xFFFF, BSS,
  1991.     "BTST",  0x0000, 0, EA05c | Exten | Bit811,
  1992.     "BVC",   0x6800, Brnch, 0,
  1993.     "BVS",   0x6900, Brnch, 0,
  1994.     "CHK",   0x4180, Rx911, EA05b,
  1995.     "CLR",   0x4200, 0, Size67 | EA05e,
  1996.     "CMP",   0xB000, OpM68C, EA05a,
  1997.     "CMPA",  0xB000, OpM68A, EA05a,
  1998.     "CMPI",  0x0C00, 0, Size67 | EA05e | Exten,
  1999.     "CMPM",  0xB108, Rx911 | Ry02, Size67,
  2000.     "CNOP",  0,      0xFFFF, Cnop,
  2001.     "CODE",  0,      0xFFFF, CSeg,
  2002.     "CSEG",  0,      0xFFFF, CSeg,
  2003.     "DATA",  0,      0xFFFF, DSeg,
  2004.     "DBCC",  0x54C8, DecBr, 0,
  2005.     "DBCS",  0x55C8, DecBr, 0,
  2006.     "DBEQ",  0x57C8, DecBr, 0,
  2007.     "DBF",   0x51C8, DecBr, 0,
  2008.     "DBGE",  0x5CC8, DecBr, 0,
  2009.     "DBGT",  0x5EC8, DecBr, 0,
  2010.     "DBHI",  0x52C8, DecBr, 0,
  2011.     "DBLE",  0x5FC8, DecBr, 0,
  2012.     "DBLS",  0x53C8, DecBr, 0,
  2013.     "DBLT",  0x5DC8, DecBr, 0,
  2014.     "DBMI",  0x5BC8, DecBr, 0,
  2015.     "DBNE",  0x56C8, DecBr, 0,
  2016.     "DBPL",  0x5AC8, DecBr, 0,
  2017.     "DBRA",  0x51C8, DecBr, 0,
  2018.     "DBT",   0x50C8, DecBr, 0,
  2019.     "DBVC",  0x58C8, DecBr, 0,
  2020.     "DBVS",  0x59C8, DecBr, 0,
  2021.     "DC",    0,      0xFFFF, DC,
  2022.     "DCB",   0,      0xFFFF, DCB,
  2023.     "DIVS",  0x81C0, Rx911, EA05b,
  2024.     "DIVU",  0x80C0, Rx911, EA05b,
  2025.     "DS",    0,      0xFFFF, DS,
  2026.     "DSEG",  0,      0xFFFF, DSeg,
  2027.     "END",   0,      0xFFFF, End,
  2028.     "ENDC",  0,      0xFFFF, EndC,
  2029.     "ENDIF", 0,      0xFFFF, EndC,
  2030.     "EOR",   0xB000, OpM68X, EA05e,
  2031.     "EORI",  0x0A00, 0, Size67 | EA05e | Exten,
  2032.     "EQU",   0,      0xFFFF, Equ,
  2033.     "EQUR",  0,      0xFFFF, Equr,
  2034.     "EVEN",  0,      0xFFFF, Even,
  2035.     "EXG",   0xC100, OpM37, 0,
  2036.     "EXT",   0x4800, OpM68S, 0,
  2037.     "FAR",   0,      0xFFFF, Far,
  2038.     "IDNT",  0,      0xFFFF, Idnt,
  2039.     "IFC",   0,      0xFFFF, IfC,
  2040.     "IFD",   0,      0xFFFF, IfD,
  2041.     "IFEQ",  0,      0xFFFF, IfEQ,
  2042.     "IFGE",  0,      0xFFFF, IfGE,
  2043.     "IFGT",  0,      0xFFFF, IfGT,
  2044.     "IFLE",  0,      0xFFFF, IfLE,
  2045.     "IFLT",  0,      0xFFFF, IfLT,
  2046.     "IFNC",  0,      0xFFFF, IfNC,
  2047.     "IFND",  0,      0xFFFF, IfND,
  2048.     "IFNE",  0,      0xFFFF, IfNE,
  2049.     "ILLEGAL", 0x4AFC, 0, 0,
  2050.     "INCLUDE", 0,    0xFFFF, Include,
  2051.     "JMP",   0x4EC0, 0, EA05f,
  2052.     "JSR",   0x4E80, 0, EA05f,
  2053.     "LEA",   0x41C0, Rx911, EA05f,
  2054.     "LINK",  0x4E50, Ry02, Exten,
  2055.     "LIST",  0,      0xFFFF, DoList,
  2056.     "LSL",   0xE308, CntR911, 0,
  2057.     "LSR",   0xE208, CntR911, 0,
  2058.     "MACRO", 0,      0xFFFF, Macro,
  2059.     "MOVE",  0x0000, 0, Sz1213A | EA611,
  2060.     "MOVEA", 0x0040, Rx911, Sz1213 | EA05a,
  2061.     "MOVEM", 0x4880, 0, Size6 | EA05z | Exten,
  2062.     "MOVEP", 0x0008, OpM68R, Exten,
  2063.     "MOVEQ", 0x7000, Data07, 0,
  2064.     "MULS",  0xC1C0, Rx911, EA05b,
  2065.     "MULU",  0xC0C0, Rx911, EA05b,
  2066.     "NBCD",  0x4800, 0, EA05e,
  2067.     "NEAR",  0,      0xFFFF, Near,
  2068.     "NEG",   0x4400, 0, Size67 | EA05e,
  2069.     "NEGX",  0x4000, 0, Size67 | EA05e,
  2070.     "NOL",   0,      0xFFFF, NoList,
  2071.     "NOLIST",0,      0xFFFF, NoList,
  2072.     "NOP",   0x4E71, 0, 0,
  2073.     "NOT",   0x4600, 0, Size67 | EA05e,
  2074.     "OR",    0x8000, OpM68D, EA05x,
  2075.     "ORG",   0,      0xFFFF, Org,
  2076.     "ORI",   0x0000, 0, Size67 | EA05e | Exten,
  2077.     "PAGE",  0,      0xFFFF, Page,
  2078.     "PEA",   0x4840, 0, EA05f,
  2079.     "PUBLIC",0,      0xFFFF, Public,
  2080.     "REG",   0,      0xFFFF, Reg,
  2081.     "RESET", 0x4E70, 0, 0,
  2082.     "ROL",   0xE718, CntR911, 0,
  2083.     "ROR",   0xE618, CntR911, 0,
  2084.     "RORG",  0,      0xFFFF, Org,
  2085.     "ROXL",  0xE510, CntR911, 0,
  2086.     "ROXR",  0xE410, CntR911, 0,
  2087.     "RTE",   0x4E73, 0, 0,
  2088.     "RTR",   0x4E77, 0, 0,
  2089.     "RTS",   0x4E75, 0, 0,
  2090.     "SBCD",  0x8100, Rx911 | RegMem3 | Ry02, 0,
  2091.     "SCC",   0x54C0, 0, EA05e,
  2092.     "SCS",   0x55C0, 0, EA05e,
  2093.     "SECTION", 0,    0xFFFF, Section,
  2094.     "SEQ",   0x57C0, 0, EA05e,
  2095.     "SET",   0,      0xFFFF, Set,
  2096.     "SF",    0x51C0, 0, EA05e,
  2097.     "SGE",   0x5CC0, 0, EA05e,
  2098.     "SGT",   0x5EC0, 0, EA05e,
  2099.     "SHI",   0x52C0, 0, EA05e,
  2100.     "SLE",   0x5FC0, 0, EA05e,
  2101.     "SLS",   0x53C0, 0, EA05e,
  2102.     "SLT",   0x5DC0, 0, EA05e,
  2103.     "SMI",   0x5BC0, 0, EA05e,
  2104.     "SNE",   0x56C0, 0, EA05e,
  2105.     "SPC",   0,      0xFFFF, Space,
  2106.     "SPL",   0x5AC0, 0, EA05e,
  2107.     "ST",    0x50C0, 0, EA05e,
  2108.     "STOP",  0x4E72, 0, Exten,
  2109.     "SUB",   0x9000, OpM68D, EA05y,
  2110.     "SUBA",  0x9000, OpM68A, EA05a,
  2111.     "SUBI",  0x0400, 0, Size67 | EA05e | Exten,
  2112.     "SUBQ",  0x5100, Data911, Size67 | EA05d,
  2113.     "SUBX",  0x9100, Rx911 | RegMem3 | Ry02, Size67,
  2114.     "SVC",   0x58C0, 0, EA05e,
  2115.     "SVS",   0x59C0, 0, EA05e,
  2116.     "SWAP",  0x4840, Ry02, 0,
  2117.     "TAS",   0x4AC0, 0, EA05e,
  2118.     "TITLE", 0,      0xFFFF, Title,
  2119.     "TRAP",  0x4E40, Data03, 0,
  2120.     "TRAPV", 0x4E76, 0, 0,
  2121.     "TST",   0x4A00, 0, Size67 | EA05e,
  2122.     "UNLK",  0x4E58, Ry02, 0,
  2123.     "XDEF",  0,      0xFFFF, Xdef,
  2124.     "XREF",  0,      0xFFFF, Xref,
  2125.     "",0,0,0};          /* End-of-table flag */
  2126.  
  2127.  
  2128.  
  2129.     if (maxinst    == 0) {        /* Determine size of opcode table */
  2130.     while (MnemTab[maxinst].Mnem[0])
  2131.         maxinst++;
  2132.     limits[0] = 0;
  2133.     limits['Z'-'A'+1] = maxinst;
  2134.     mid = 0;
  2135.     for (lower = 0;    lower <    maxinst; lower++) {
  2136.         upper = (unsigned int) MnemTab[lower].Mnem[0] - 'A' + 1;
  2137.         if (upper != mid) {
  2138.         if (upper > 0) {    /* Start of the    next letter */
  2139.             mid++;
  2140.             while (mid < upper)
  2141.             limits[mid++] =    lower;
  2142.             limits[mid]    = lower;
  2143.         }
  2144.         }
  2145.     }
  2146.     mid++;
  2147.     while (mid < 'Z'-'A'+1) {
  2148.         limits[mid++] = maxinst;    /* In case we didn't get to Z */
  2149.     }
  2150.     }
  2151.     mid    = (unsigned int) OpCode[0] - 'A' + 1;
  2152.     if (mid < 0) {            /* This    catches    stuff like "=" */
  2153.     lower =    0;
  2154.     upper =    limits[1];
  2155.     } else if (mid > 'Z'-'A'+1) {
  2156.     lower =    upper =    0;        /* Reject this one */
  2157.     } else {
  2158.     lower =    limits[mid++];
  2159.     upper =    limits[mid];
  2160.     }
  2161.     while (lower < upper) {
  2162.     mid = (lower + upper) /    2;    /* Search opcode table */
  2163.     for (i = OpCode, j = MnemTab[mid].Mnem;    *i == *j; i++, j++)
  2164.         if (*i == '\0')
  2165.         break;        /* Find    first non-match    */
  2166.     if (*i < *j)
  2167.         upper = mid;    /* Search lower    half of    table */
  2168.     else if    (*i > *j)
  2169.         lower = mid    + 1;    /* Search upper    half of    table */
  2170.     else if    (MnemTab[mid].AMA != 0xFFFF) {    /* Found it */
  2171.         Op = MnemTab[mid].OpBits;    /* Executable instruction */
  2172.         AdrModeA = MnemTab[mid].AMA;
  2173.         AdrModeB = MnemTab[mid].AMB;
  2174.         Dir    = None;
  2175.         return (TRUE);
  2176.     } else {
  2177.         Op = AdrModeA = AdrModeB = 0;    /* Directive */
  2178.         Dir    = MnemTab[mid].AMB;
  2179.         return (TRUE);
  2180.     }
  2181.     }
  2182.     Op = AdrModeA = AdrModeB = Dir = 0;
  2183.     return (FALSE);            /* Didn't find it */
  2184. }
  2185. SHAR_EOF
  2186. #    End of shell archive
  2187. exit 0
  2188. -- 
  2189. Bob Page, U of Lowell CS Dept.  page@swan.ulowell.edu  ulowell!page
  2190. Have five nice days.
  2191.